# Upgrade Error - rake db:migrate index on theme\_field\_id

**URL:** https://meta.discourse.org/t/upgrade-error-rake-db-migrate-index-on-theme-field-id/278935
**Category:** Self-hosting
**Tags:** two-container, ai
**Created:** [September 13, 2023, 9:05pm UTC](https://meta.discourse.org/t/upgrade-error-rake-db-migrate-index-on-theme-field-id/278935 "2023-09-13T21:05:56Z")
**Posts on this page:** 11
**Page:** 1

<div class="post-metadata">

### Author: ![Joshua\_Lyon](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/joshua_lyon/32/117236_2.png) [@Joshua\_Lyon](https://meta.discourse.org/u/Joshua_Lyon)
#### Post date: [September 13, 2023, 9:05pm UTC](https://meta.discourse.org/t/upgrade-error-rake-db-migrate-index-on-theme-field-id/278935/1 "2023-09-13T21:05:56Z")

</div>

In the latest [release notes (3.2.0.beta1)](https://meta.discourse.org/t/3-2-0-beta1-discourse-picturephone-begins-chat-global-mention-warnings-digest-suppression-by-tags-and-more/277212), I noticed the `discourse-ai` plugin which I hadn’t seen before, so I attempted to add this plugin and upgrade my discourse instance at the same time.

As mentioned in the title, I’m currently seeing an error in the bootstrap where the `rake db:migrate` is failing to creat a unique index on `theme_field_id`. Here’s some details on how I go to that point though…

### Initial Upgrade Attempt (patch-package error)

I’m running a split container install, so I:

- Edited my web\_only.yml to add the new `discourse-ai` plugin

- Ran `./launcher bootstrap web_only`

It errored out with a message about `patch-package` not being found.

### Git Pull → boostrap (pg-vector error)

I figured I would make sure I had the latest launcher updates as it wouldn’t hurt before rertrying:

- Ran a `git pull` to make sure I had the latest launcher related updates
- Ran `./launcher bootstrap web_only` again

This time I received error messages related `pg-vector`.

> [📄 Log snippet from bootstrap \*with\* `discourse-ai`](https://gist.github.com/joshualyon/27f462b92960a892af5270a457531afb)

I noted down my PostgreSQL versions so I’d have them for my records when I decided to revisit the `discourse-ai` plugin.

- **web\_only** :
  - client: `psql (PostgreSQL) 13.10 (Debian 13.10-1.pgdg110+1)`

- **data** :
  - server: `PostgreSQL 13.9 (Debian 13.9-1.pgdg110+1)`

### Remove `discourse-ai` Plugin → Bootstrap

And then I removed the `discourse-ai` plugin the the `web_only.yml` file and ran a bootstrap again.

Much to my surprise, I was still seeing errors, but this time they appear to be related to `rake db:migrate` not being able to create a unique index `index_javascript_caches_on_theme_field_id` with the detail: Key (theme\_field\_id)=(3) is duplicated.

> [📄 Log snippet from bootstrap \*without\* `discourse-ai`](https://gist.github.com/joshualyon/4412d1ff6d0252d1d11be6881e2345e0)

### Your help? 🙏

That brings me here looking for help. I figured I should take a pause and get some insights from the community before digging in further in case anyone else has seen this before.

For reference, I have 3.2.0.beta1-dev ([993ed10cf0](https://github.com/discourse/discourse/commits/993ed10cf0022061e41955ba7395eab578736928) ~ August 9th) installed.

And while I don’t think it’s related to this, I figure it doesn’t hurt to mention that I migrated between host machines at the start of this year… though I’ve done several Discourse updates through the admin UI since then.

> **Migration approach**
>
> From memory, this was basically upgrading the source instance to the latest Discourse version, Installing discourse on the new host, freezing the source, doing a Discourse backup on the source, `rsync` images/etc between hosts, restore backup on new host.

---

<div class="post-metadata">

### Author: ![JammyDodger](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/jammydodger/32/254611_2.png) [@JammyDodger](https://meta.discourse.org/u/JammyDodger)
#### Post date: [September 13, 2023, 9:29pm UTC](https://meta.discourse.org/t/upgrade-error-rake-db-migrate-index-on-theme-field-id/278935/2 "2023-09-13T21:29:35Z")

</div>

For the duplicate index errors, I think if you can `restart web_only` and deal with them from the UI it’s much simpler than doing it in the database. Though I don’t think I’ve seen one on `theme_field_id` before.

The line just above `rake aborted!` in the logs mentions `discourse-voting` now being `discourse-topic-voting`. You could try and update the link in the plugin section to the current one and see if that helps?

---

<div class="post-metadata">

### Author: ![Joshua\_Lyon](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/joshua_lyon/32/117236_2.png) [@Joshua\_Lyon](https://meta.discourse.org/u/Joshua_Lyon)
#### Post date: [September 13, 2023, 9:33pm UTC](https://meta.discourse.org/t/upgrade-error-rake-db-migrate-index-on-theme-field-id/278935/3 "2023-09-13T21:33:43Z")

</div>

> [@JammyDodger](#):
>
> For the duplicate index errors, I think if you can `restart web_only` and deal with them from the UI it’s much simpler than doing it in the database. Though I don’t think I’ve seen one on `theme_field_id` before.

Can you clarify what resource it’s referring to as having a duplicate ID? I wasn’t sure exactly what `theme_field_id` refers to.

For the record, I hadn’t shut down the `web_only` container. I usually bootstrap the container first to minimize the outage window:

> [@Faster rebuilds?](https://meta.discourse.org/t/faster-rebuilds/40341/13):
>
> ```plaintext
> ./launcher bootstrap web_only
> 
> ```
> 
> Start outage
> 
> ```plaintext
> ./launcher destroy web_only
> ./launcher start web_only
> 
> ```
> 
> End outage

–

> [@JammyDodger](#):
>
> mentions `discourse-voting` now being `discourse-topic-voting`. You could try and update the link in the plugin section to the current one and see if that helps?

I’ll give it a try. I suspect it won’t help as I would think GitHub is redirecting things silently behind the scenes and it’s just a warning on the Discourse side. 🙂

---

<div class="post-metadata">

### Author: ![JammyDodger](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/jammydodger/32/254611_2.png) [@JammyDodger](https://meta.discourse.org/u/JammyDodger)
#### Post date: [September 13, 2023, 9:38pm UTC](https://meta.discourse.org/t/upgrade-error-rake-db-migrate-index-on-theme-field-id/278935/4 "2023-09-13T21:38:12Z")

</div>

> [@Joshua\_Lyon](#):
>
> Can you clarify what resource it’s referring to as having a duplicate ID? I wasn’t sure exactly what `theme_field_id` refers to.

If you have an up-and-running site with the [data explorer](https://meta.discourse.org/t/32566?silent=true) installed, I think you should be able to get a look at what that may be referring to using this query:

```sql
SELECT *
FROM theme_fields
WHERE id = 3

```

---

<div class="post-metadata">

### Author: ![Joshua\_Lyon](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/joshua_lyon/32/117236_2.png) [@Joshua\_Lyon](https://meta.discourse.org/u/Joshua_Lyon)
#### Post date: [September 13, 2023, 10:01pm UTC](https://meta.discourse.org/t/upgrade-error-rake-db-migrate-index-on-theme-field-id/278935/5 "2023-09-13T22:01:02Z")

</div>

I wasn’t aware of that plugin - that’s neat! I don’t have it installed, but I’m able to enter the data container and run queries though.

That’s a great clue! If I’m reading the error message correctly though, I don’t think it’s on the `theme_fields` table as that particular table doesn’t have a `theme_field_id`. I haven’t checked the source code, but I would hazard a guess that the first argument to `add_index()` is the table name and the second is the column.

Based on that, it looks like it would be the `javascript_caches` table.

```plaintext
== 20230817174049 EnsureJavascriptCacheIsUniquePerTheme: migrating ============
-- remove_index(:javascript_caches, :theme_id)
   -> 0.0208s
-- add_index(:javascript_caches, :theme_id, {:unique=>true})
   -> 0.0079s
-- remove_index(:javascript_caches, :theme_field_id)
   -> 0.0026s
-- add_index(:javascript_caches, :theme_field_id, {:unique=>true})

```

So I checked the structure of that table and it has the `theme_field_id` column:

```plaintext
discourse=# \d javascript_caches
                                          Table "public.javascript_caches"
     Column | Type | Collation | Nullable | Default
----------------+-----------------------------+-----------+----------+-----------------------------------------------
 id | bigint | | not null | nextval('javascript_caches_id_seq'::regclass)
 theme_field_id | bigint | | |
 digest | character varying | | |
 content | text | | not null |
 created_at | timestamp without time zone | | not null |
 updated_at | timestamp without time zone | | not null |
 theme_id | bigint | | |
 source_map | text | | |
Indexes:
    "javascript_caches_pkey" PRIMARY KEY, btree (id)
    "index_javascript_caches_on_digest" btree (digest)
    "index_javascript_caches_on_theme_field_id" btree (theme_field_id)
    "index_javascript_caches_on_theme_id" btree (theme_id)
Check constraints:
    "enforce_theme_or_theme_field" CHECK (theme_id IS NOT NULL AND theme_field_id IS NULL OR theme_id IS NULL AND theme_field_id IS NOT NULL)
Foreign-key constraints:
    "fk_rails_58f94aecc4" FOREIGN KEY (theme_id) REFERENCES themes(id) ON DELETE CASCADE
    "fk_rails_ed33506dbd" FOREIGN KEY (theme_field_id) REFERENCES theme_fields(id) ON DELETE CASCADE

```

I was able to query that table (with the content fields shortened so I could actually read it) and I can see the duplicates. But I’m not sure what the implication of these duplicates are.

```plaintext
discourse=# select id, theme_field_id, digest, substring(content from 1 for 64) as content_64, created_at, updated_at, theme_id, substring(source_map from 1 for 64) as source_64 from javascript_caches where theme_field_id = 3;
 id | theme_field_id | digest | content_64 | created_at | updated_at | theme_id | source_64
----+----------------+------------------------------------------+------------------------------------------------------------------+----------------------------+----------------------------+----------+------------------------------------------------------------------
  1 | 3 | d0b6ec642d5649064ff0501cadc775a9217b16e0 | "define"in window&&define("discourse/theme-3/initializers/theme- | 2019-02-25 01:26:56.606537 | 2023-08-18 20:47:19.596923 | | {"version":3,"sources":["discourse/initializers/theme-field-3-co
  2 | 3 | 7fd74ecf4448afccdbcd9ccde87acddb4ec6f514 | "define"in window&&define("discourse/theme-3/initializers/theme- | 2019-02-25 01:26:58.228209 | 2023-08-18 20:50:41.049209 | | {"version":3,"sources":["discourse/initializers/theme-field-3-co

```

The content looked familiar, so I went into the Customize → Theme → My Theme → Common → Head, made a minor tweak and saved and I can see that one of the entries was updated and one of them remains old…

```plaintext
discourse=# select id, theme_field_id, digest, substring(content from 1 for 64) as content_64, created_at, updated_at, theme_id, substring(source_map from 1 for 64) as source_64 from javascript_caches where theme_field_id = 3;
 id | theme_field_id | digest | content_64 | created_at | updated_at | theme_id | source_64
----+----------------+------------------------------------------+------------------------------------------------------------------+----------------------------+----------------------------+----------+------------------------------------------------------------------
  2 | 3 | 7fd74ecf4448afccdbcd9ccde87acddb4ec6f514 | "define"in window&&define("discourse/theme-3/initializers/theme- | 2019-02-25 01:26:58.228209 | 2023-08-18 20:50:41.049209 | | {"version":3,"sources":["discourse/initializers/theme-field-3-co
  1 | 3 | 7f4132b1f9ced1b90b8f8fc24812cc11e81fea8d | "define"in window&&define("discourse/theme-3/initializers/theme- | 2019-02-25 01:26:56.606537 | 2023-09-13 21:56:56.312263 | | {"version":3,"sources":["discourse/initializers/theme-field-3-co
(2 rows)

```

Again, I’m not sure what the implication of these duplicates are, if it’s safe to delete the ‘old’ one, or if there’s some other way to ‘rebuild’ the caches which would clean this up?

---

<div class="post-metadata">

### Author: ![JammyDodger](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/jammydodger/32/254611_2.png) [@JammyDodger](https://meta.discourse.org/u/JammyDodger)
#### Post date: [September 13, 2023, 10:11pm UTC](https://meta.discourse.org/t/upgrade-error-rake-db-migrate-index-on-theme-field-id/278935/6 "2023-09-13T22:11:10Z")

</div>

To be honest, I’m 0/2 on this so far so I am likely not the best source of info for this one. 🙂

There are a couple of previous topics where a similar thing has happened for `index_tags_on_name` if they could be any use? eg.

> [@Error upgrading from 3.0.1 to 3.1.0](https://meta.discourse.org/t/error-upgrading-from-3-0-1-to-3-1-0/259712):
>
> Hello! Here’s are my log details: I, [2023-03-28T15:29:11.675436 #1] INFO -- : Terminating async processes I, [2023-03-28T15:29:11.675493 #1] INFO -- : Sending INT to HOME=/var/lib/postgresql USER=postgres exec chpst -u postgres:postgres:ssl-cert -U postgres:postgres:ssl-cert /usr/lib/postgresql/13/bin/postmaster -D /etc/postgresql/13/main pid: 42 I, [2023-03-28T15:29:11.675526 #1] INFO -- : Sending TERM to exec chpst -u redis -U redis /usr/bin/redis-server /etc/redis/redis.conf pid: 103 10…

---

<div class="post-metadata">

### Author: ![pfaffman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pfaffman/32/120154_2.png) [@pfaffman](https://meta.discourse.org/u/pfaffman)
#### Post date: [September 13, 2023, 11:17pm UTC](https://meta.discourse.org/t/upgrade-error-rake-db-migrate-index-on-theme-field-id/278935/7 "2023-09-13T23:17:11Z")

</div>

Rebuild your data container. The ai plugin requires a extension you don’t have yet.

---

<div class="post-metadata">

### Author: ![Joshua\_Lyon](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/joshua_lyon/32/117236_2.png) [@Joshua\_Lyon](https://meta.discourse.org/u/Joshua_Lyon)
#### Post date: [September 14, 2023, 2:46pm UTC](https://meta.discourse.org/t/upgrade-error-rake-db-migrate-index-on-theme-field-id/278935/8 "2023-09-14T14:46:27Z")

</div>

> [@JammyDodger](#):
>
> To be honest, I’m 0/2 on this so far so I am likely not the best source of info for this one. 🙂

I appreciate your help! Seems like you led me down the right path. 🤩

I took a backup of the table with `pg_dump`, deleted the old duplicate entry, and the bootstrap completed successfully. 👍

> [@pfaffman](#):
>
> Rebuild your data container. The ai plugin requires a extension you don’t have yet.

Thanks for the confirmation! I figured I might need to update the data container (or otherwise get pgvector installed). I was holding off on doing that as I didn’t want to deal with the downtime.

From the discourse-ai thread, it sounds like PG15 is on the horizon, so I might just wait a bit for that.

It seems like the pgvector dependency might be for the Embeddings feature which I didn’t plan on using, but unfortunately it sounds like it’s all bundled together. I mainly just wanted to play with some of the OpenAI / ChatGPT magic rewrite features, so perhaps one more reason to wait until the next big data container update. 🙂

---

<div class="post-metadata">

### Author: ![pfaffman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pfaffman/32/120154_2.png) [@pfaffman](https://meta.discourse.org/u/pfaffman)
#### Post date: [September 14, 2023, 3:10pm UTC](https://meta.discourse.org/t/upgrade-error-rake-db-migrate-index-on-theme-field-id/278935/9 "2023-09-14T15:10:30Z")

</div>

> [@Joshua\_Lyon](#):
>
> From the discourse-ai thread, it sounds like PG15 is on the horizon, so I might just wait a bit for that.

You can wait if you want, but single-container people (which is the vast majority of self-hosters) upgrade their postgres potentially every time they do an upgrade, so there’s not much reason to wait other than a few extra minutes of downtime. You’ll need to rebuild (or maybe just destroy and start) the web\_only container after the database rebuild.

---

<div class="post-metadata">

### Author: ![Joshua\_Lyon](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/joshua_lyon/32/117236_2.png) [@Joshua\_Lyon](https://meta.discourse.org/u/Joshua_Lyon)
#### Post date: [September 14, 2023, 3:28pm UTC](https://meta.discourse.org/t/upgrade-error-rake-db-migrate-index-on-theme-field-id/278935/10 "2023-09-14T15:28:49Z")

</div>

> [@pfaffman](#):
>
> a few extra minutes of downtime

That’s the main reason. Even if it’s only a few minutes, I’d rather rather minimize it if it’s not critical.

On that note, I probably should be holding off on using a beta plugin for the potential for downtime alone. 😛

I’ve loosely followed some of the discussions on ‘zero downtime’ upgrades. Perhaps it’s just rose-colored glasses looking back on recent history, but it feels like I’ve been able to use `/admin/upgrade` for most updates over the past year, so I’ve been focused on more critical projects for the time being and lost interest in the zero downtime approach.

When I migrated to a bigger host back in January, it was ‘zero downtime’ in that users could continue to access content on the site, but there was a brief period where things were read-only as we transitioned. I suppose I could use that approach for a major `data` container upgrade if I really wanted to minimize downtime during the next big `data` upgrade.

PS. I’ve read a _ton_ of your posts in the community here over the years. Thanks for all your efforts in supporting the community! 🌟

---

<div class="post-metadata">

### Author: ![pfaffman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pfaffman/32/120154_2.png) [@pfaffman](https://meta.discourse.org/u/pfaffman)
#### Post date: [September 14, 2023, 9:25pm UTC](https://meta.discourse.org/t/upgrade-error-rake-db-migrate-index-on-theme-field-id/278935/11 "2023-09-14T21:25:53Z")

</div>

> [@Joshua\_Lyon](#):
>
> it feels like I’ve been able to use `/admin/upgrade` for most updates over the past year,

It really does! I haven’t done an upgrade for my “rebuilds when you need them” clients in quite a while. For sites like yours my dashboard will do the rebuild and do the post upgrade migrations after the new container has launched (if your existing container has those migrations set to not run the first time).
