# "discourse\_solved\_solved\_topics" violates not-null constraint during rebuild

**URL:** https://meta.discourse.org/t/discourse-solved-solved-topics-violates-not-null-constraint-during-rebuild/391813
**Category:** Support
**Tags:** solved
**Created:** [December 20, 2025, 6:30pm UTC](https://meta.discourse.org/t/discourse-solved-solved-topics-violates-not-null-constraint-during-rebuild/391813 "2025-12-20T18:30:38Z")
**Posts on this page:** 10
**Page:** 1

<div class="post-metadata">

### Author: ![Steven](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/steven/32/187890_2.png) [@Steven](https://meta.discourse.org/u/Steven)
#### Post date: [December 20, 2025, 6:30pm UTC](https://meta.discourse.org/t/discourse-solved-solved-topics-violates-not-null-constraint-during-rebuild/391813/1 "2025-12-20T18:30:38Z")

</div>

Hello everyone!

During a rebuild on a forum in the #stable branch, I have an error related to the #solved plugin.

Here are the logs:

```plaintext
2025-12-20 03:48:21.715 UTC [1122] discourse@discourse ERROR: null value in column "answer_post_id" of relation "discourse_solved_solved_topics" violates not-null constraint
2025-12-20 03:48:21.715 UTC [1122] discourse@discourse DETAIL: Failing row contains (3735, 35506, null, -1, null, 2021-05-12 18:38:58.11516, 2021-05-12 18:38:58.11516).
2025-12-20 03:48:21.715 UTC [1122] discourse@discourse STATEMENT: INSERT INTO discourse_solved_solved_topics (
	  topic_id,
	  answer_post_id,
	  topic_timer_id,
	  accepter_user_id,
	  created_at,
	  updated_at
	)
	SELECT
	  tc.topic_id,
	  tc.answer_post_id,
	  tc.topic_timer_id,
	  tc.accepter_user_id,
	  tc.created_at,
	  tc.updated_at
	FROM (
	  SELECT
	    tc.topic_id,
	    CAST(tc.value AS INTEGER) AS answer_post_id,
	    CAST(tc2.value AS INTEGER) AS topic_timer_id,
	    COALESCE(ua.acting_user_id, -1) AS accepter_user_id,
	    tc.created_at,
	    tc.updated_at,
	    ROW_NUMBER() OVER (PARTITION BY tc.topic_id ORDER BY tc.created_at ASC) AS rn_topic,
	    ROW_NUMBER() OVER (PARTITION BY CAST(tc.value AS INTEGER) ORDER BY tc.created_at ASC) AS rn_answer
	  FROM topic_custom_fields tc
	  LEFT JOIN topic_custom_fields tc2 ON tc2.topic_id = tc.topic_id AND tc2.name = 'solved_auto_close_topic_timer_id'
	  LEFT JOIN user_actions ua ON ua.target_topic_id = tc.topic_id AND ua.action_type = 15
	  WHERE tc.name = 'accepted_answer_post_id'
	    AND tc.id > 0
	    AND tc.id <= 0 + 10000
	) tc
	WHERE tc.rn_topic = 1 AND tc.rn_answer = 1
	ON CONFLICT DO NOTHING
	
rake aborted!
StandardError: An error has occurred, all later migrations canceled: (StandardError)

ERROR: null value in column "answer_post_id" of relation "discourse_solved_solved_topics" violates not-null constraint
DETAIL: Failing row contains (3735, 35506, null, -1, null, 2021-05-12 18:38:58.11516, 2021-05-12 18:38:58.11516).
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/rack-mini-profiler-4.0.1/lib/patches/db/pg/alias_method.rb:109:in `exec'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/rack-mini-profiler-4.0.1/lib/patches/db/pg/alias_method.rb:109:in `async_exec'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/mini_sql-1.6.0/lib/mini_sql/postgres/connection.rb:217:in `run'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/mini_sql-1.6.0/lib/mini_sql/active_record_postgres/connection.rb:38:in `block in run'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/mini_sql-1.6.0/lib/mini_sql/active_record_postgres/connection.rb:34:in `block in with_lock'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activesupport-8.0.2.1/lib/active_support/concurrency/null_lock.rb:9:in `synchronize'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/mini_sql-1.6.0/lib/mini_sql/active_record_postgres/connection.rb:34:in `with_lock'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/mini_sql-1.6.0/lib/mini_sql/active_record_postgres/connection.rb:38:in `run'
/var/www/discourse/lib/mini_sql_multisite_connection.rb:109:in `run'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/mini_sql-1.6.0/lib/mini_sql/postgres/connection.rb:196:in `exec'
/var/www/discourse/plugins/discourse-solved/db/migrate/20250318024953_copy_solved_topic_custom_field_to_discourse_solved_solved_topics.rb:17:in `up'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activerecord-8.0.2.1/lib/active_record/migration.rb:994:in `public_send'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activerecord-8.0.2.1/lib/active_record/migration.rb:994:in `exec_migration'
/var/www/discourse/lib/freedom_patches/schema_migration_details.rb:8:in `block in exec_migration'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/benchmark-0.4.1/lib/benchmark.rb:305:in `measure'
/var/www/discourse/lib/freedom_patches/schema_migration_details.rb:8:in `exec_migration'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activerecord-8.0.2.1/lib/active_record/migration.rb:975:in `block (2 levels) in migrate'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activesupport-8.0.2.1/lib/active_support/benchmark.rb:17:in `realtime'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activerecord-8.0.2.1/lib/active_record/migration.rb:974:in `block in migrate'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activerecord-8.0.2.1/lib/active_record/connection_adapters/abstract/connection_pool.rb:412:in `with_connection'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activerecord-8.0.2.1/lib/active_record/migration.rb:973:in `migrate'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activerecord-8.0.2.1/lib/active_record/migration.rb:1187:in `migrate'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activerecord-8.0.2.1/lib/active_record/migration.rb:1535:in `block in execute_migration_in_transaction'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activerecord-8.0.2.1/lib/active_record/migration.rb:1588:in `ddl_transaction'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activerecord-8.0.2.1/lib/active_record/migration.rb:1534:in `execute_migration_in_transaction'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activerecord-8.0.2.1/lib/active_record/migration.rb:1509:in `each'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activerecord-8.0.2.1/lib/active_record/migration.rb:1509:in `migrate_without_lock'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activerecord-8.0.2.1/lib/active_record/migration.rb:1454:in `block in migrate'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activerecord-8.0.2.1/lib/active_record/migration.rb:1606:in `with_advisory_lock'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activerecord-8.0.2.1/lib/active_record/migration.rb:1454:in `migrate'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activerecord-8.0.2.1/lib/active_record/migration.rb:1261:in `up'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activerecord-8.0.2.1/lib/active_record/migration.rb:1236:in `migrate'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activerecord-8.0.2.1/lib/active_record/tasks/database_tasks.rb:270:in `migrate'
/var/www/discourse/lib/tasks/db.rake:267:in `block (2 levels) in <main>'
/var/www/discourse/lib/distributed_mutex.rb:53:in `block in synchronize'
/var/www/discourse/lib/distributed_mutex.rb:49:in `synchronize'
/var/www/discourse/lib/distributed_mutex.rb:49:in `synchronize'
/var/www/discourse/lib/distributed_mutex.rb:34:in `synchronize'
/var/www/discourse/lib/tasks/db.rake:242:in `block in <main>'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/rake-13.3.0/exe/rake:27:in `<top (required)>'
/usr/local/bin/bundle:25:in `load'
/usr/local/bin/bundle:25:in `<main>'

Caused by:
PG::NotNullViolation: ERROR: null value in column "answer_post_id" of relation "discourse_solved_solved_topics" violates not-null constraint (PG::NotNullViolation)
DETAIL: Failing row contains (3735, 35506, null, -1, null, 2021-05-12 18:38:58.11516, 2021-05-12 18:38:58.11516).
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/rack-mini-profiler-4.0.1/lib/patches/db/pg/alias_method.rb:109:in `exec'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/rack-mini-profiler-4.0.1/lib/patches/db/pg/alias_method.rb:109:in `async_exec'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/mini_sql-1.6.0/lib/mini_sql/postgres/connection.rb:217:in `run'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/mini_sql-1.6.0/lib/mini_sql/active_record_postgres/connection.rb:38:in `block in run'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/mini_sql-1.6.0/lib/mini_sql/active_record_postgres/connection.rb:34:in `block in with_lock'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activesupport-8.0.2.1/lib/active_support/concurrency/null_lock.rb:9:in `synchronize'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/mini_sql-1.6.0/lib/mini_sql/active_record_postgres/connection.rb:34:in `with_lock'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/mini_sql-1.6.0/lib/mini_sql/active_record_postgres/connection.rb:38:in `run'
/var/www/discourse/lib/mini_sql_multisite_connection.rb:109:in `run'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/mini_sql-1.6.0/lib/mini_sql/postgres/connection.rb:196:in `exec'
/var/www/discourse/plugins/discourse-solved/db/migrate/20250318024953_copy_solved_topic_custom_field_to_discourse_solved_solved_topics.rb:17:in `up'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activerecord-8.0.2.1/lib/active_record/migration.rb:994:in `public_send'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activerecord-8.0.2.1/lib/active_record/migration.rb:994:in `exec_migration'
/var/www/discourse/lib/freedom_patches/schema_migration_details.rb:8:in `block in exec_migration'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/benchmark-0.4.1/lib/benchmark.rb:305:in `measure'
/var/www/discourse/lib/freedom_patches/schema_migration_details.rb:8:in `exec_migration'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activerecord-8.0.2.1/lib/active_record/migration.rb:975:in `block (2 levels) in migrate'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activesupport-8.0.2.1/lib/active_support/benchmark.rb:17:in `realtime'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activerecord-8.0.2.1/lib/active_record/migration.rb:974:in `block in migrate'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activerecord-8.0.2.1/lib/active_record/connection_adapters/abstract/connection_pool.rb:412:in `with_connection'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activerecord-8.0.2.1/lib/active_record/migration.rb:973:in `migrate'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activerecord-8.0.2.1/lib/active_record/migration.rb:1187:in `migrate'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activerecord-8.0.2.1/lib/active_record/migration.rb:1535:in `block in execute_migration_in_transaction'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activerecord-8.0.2.1/lib/active_record/migration.rb:1588:in `ddl_transaction'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activerecord-8.0.2.1/lib/active_record/migration.rb:1534:in `execute_migration_in_transaction'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activerecord-8.0.2.1/lib/active_record/migration.rb:1509:in `each'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activerecord-8.0.2.1/lib/active_record/migration.rb:1509:in `migrate_without_lock'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activerecord-8.0.2.1/lib/active_record/migration.rb:1454:in `block in migrate'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activerecord-8.0.2.1/lib/active_record/migration.rb:1606:in `with_advisory_lock'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activerecord-8.0.2.1/lib/active_record/migration.rb:1454:in `migrate'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activerecord-8.0.2.1/lib/active_record/migration.rb:1261:in `up'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activerecord-8.0.2.1/lib/active_record/migration.rb:1236:in `migrate'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activerecord-8.0.2.1/lib/active_record/tasks/database_tasks.rb:270:in `migrate'
/var/www/discourse/lib/tasks/db.rake:267:in `block (2 levels) in <main>'
/var/www/discourse/lib/distributed_mutex.rb:53:in `block in synchronize'
/var/www/discourse/lib/distributed_mutex.rb:49:in `synchronize'
/var/www/discourse/lib/distributed_mutex.rb:49:in `synchronize'
/var/www/discourse/lib/distributed_mutex.rb:34:in `synchronize'
/var/www/discourse/lib/tasks/db.rake:242:in `block in <main>'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/rake-13.3.0/exe/rake:27:in `<top (required)>'
/usr/local/bin/bundle:25:in `load'
/usr/local/bin/bundle:25:in `<main>'
Tasks: TOP => db:migrate
(See full trace by running task with --trace)
I, [2025-12-20T03:48:21.794538 #1] INFO -- : gem install geocoder -v 1.8.3 -i /var/www/discourse/plugins/discourse-locations/gems/3.3.8 --no-document --ignore-dependencies --no-user-install
Successfully installed geocoder-1.8.3
1 gem installed
== 20250318024953 CopySolvedTopicCustomFieldToDiscourseSolvedSolvedTopics: migrating 

I, [2025-12-20T03:48:21.795736 #1] INFO -- : Terminating async processes
I, [2025-12-20T03:48:21.795838 #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/15/bin/postmaster -D /etc/postgresql/15/main pid: 45
I, [2025-12-20T03:48:21.795934 #1] INFO -- : Sending TERM to exec chpst -u redis -U redis /usr/bin/redis-server /etc/redis/redis.conf pid: 112
112:signal-handler (1766202501) Received SIGTERM scheduling shutdown...
2025-12-20 03:48:21.796 UTC [45] LOG: received fast shutdown request
2025-12-20 03:48:21.800 UTC [45] LOG: aborting any active transactions
2025-12-20 03:48:21.808 UTC [45] LOG: background worker "logical replication launcher" (PID 59) exited with exit code 1
2025-12-20 03:48:21.809 UTC [54] LOG: shutting down
2025-12-20 03:48:21.811 UTC [54] LOG: checkpoint starting: shutdown immediate
2025-12-20 03:48:21.861 UTC [54] LOG: checkpoint complete: wrote 18 buffers (0.0%); 0 WAL file(s) added, 0 removed, 0 recycled; write=0.039 s, sync=0.006 s, total=0.052 s; sync files=10, longest=0.003 s, average=0.001 s; distance=161 kB, estimate=161 kB
112:M 20 Dec 2025 03:48:21.892 # User requested shutdown...
112:M 20 Dec 2025 03:48:21.892 * Saving the final RDB snapshot before exiting.
2025-12-20 03:48:21.918 UTC [45] LOG: database system is shut down
112:M 20 Dec 2025 03:48:22.621 * DB saved on disk
112:M 20 Dec 2025 03:48:22.621 # Redis is now ready to exit, bye bye...

FAILED
--------------------
Pups::ExecError: cd /var/www/discourse && su discourse -c 'bundle exec rake db:migrate' failed with return #<Process::Status: pid 1016 exit 1>
Location of failure: /usr/local/lib/ruby/gems/3.3.0/gems/pups-1.3.0/lib/pups/exec_command.rb:131:in `spawn'
exec failed with the params {"cd"=>"$home", "tag"=>"migrate", "hook"=>"db_migrate", "cmd"=>["su discourse -c 'bundle exec rake db:migrate'"]}
bootstrap failed with exit code 1
**FAILED TO BOOTSTRAP** please scroll up and look for earlier error messages, there may be more than one.
./discourse-doctor may help diagnose the problem.

```

I managed to rebuild by deleting the solved plugin in the app.yml (using the `- rm -rf discourse-solved` command), and the owner of the forum could probably do without this plugin but I’d still like to fix this.

I don’t think the issue comes from the plugin, it may be a bad manipulation on the forum. But when I explore the database, I have at least 20-30 `\N` entries in value

Here is an extract:

| id | topic\_id | name | value | created at | updated at |
| --- | --- | --- | --- | --- | --- |
| 1579 | 35497 | accepted\_answer\_post\_id | 301435 | 2021-05-10 20:18:57.780444 | 2021-05-10 20:18:57.780444 |
| 1583 | **35506** | accepted\_answer\_post\_id | \N | 2021-05-12 18:38:58.11516 | 2021-05-12 18:38:58.11516 |
| 423 | 21211 | accepted\_answer\_post\_id | 153039 | 2019-09-04 21:01:37.811417 | 2019-09-04 21:01:37.811417 |
| 424 | 21685 | accepted\_answer\_post\_id | 156850 | 2019-09-09 04:39:28.388591 | 2019-09-09 04:39:28.388591 |
| 425 | 21711 | accepted\_answer\_post\_id | 157323 | 2019-09-11 11:51:14.375185 | 2019-09-11 11:51:14.375185 |
| 428 | 20982 | accepted\_answer\_post\_id | 157807 | 2019-09-14 08:53:16.079032 | 2019-09-14 08:53:16.079032 |
| 429 | 4949 | accepted\_answer\_post\_id | 157515 | 2019-09-16 07:57:00.862694 | 2019-09-16 07:57:00.862694 |
| 430 | 15439 | accepted\_answer\_post\_id | 158645 | 2019-09-19 00:56:20.112603 | 2019-09-19 00:56:20.112603 |
| 1603 | 35710 | accepted\_answer\_post\_id | \N | 2021-05-19 20:58:06.598697 | 2021-05-19 20:58:06.598697 |
| 701 | 25377 | accepted\_answer\_post\_id | 195459 | 2020-03-26 20:42:14.168898 | 2020-03-26 20:42:14.168898 |
| 434 | 21868 | accepted\_answer\_post\_id | 159024 | 2019-09-22 10:09:09.671605 | 2019-09-22 10:09:09.671605 |

I need to tell you that I suck at sql queries, especially via command lines. I don’t really trust myself to delete these lines via terminal.

But anyway, what route do you recommand for me to fix this? A query (what type of querie?) ? A script, or something can be done in the forum directly?

---

<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: [December 20, 2025, 7:57pm UTC](https://meta.discourse.org/t/discourse-solved-solved-topics-violates-not-null-constraint-during-rebuild/391813/2 "2025-12-20T19:57:11Z")

</div>

> [@Steven](#):
>
> the owner of the forum could probably do without this plugin

Except it’s been moved to core.

The ones where the post\_id is Newline are the issue. You should just delete those records from the database (it might be possible from rails). You can probably get [Ask.discourse.com](http://Ask.discourse.com) to tell you how.

---

<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: [December 20, 2025, 8:55pm UTC](https://meta.discourse.org/t/discourse-solved-solved-topics-violates-not-null-constraint-during-rebuild/391813/3 "2025-12-20T20:55:41Z")

</div>

> [@Steven](#):
>
> or something can be done in the forum directly?

As a possible punt… I believe deleting a topic now automatically removes the solution and deletes the record in `discourse_solved_solved_topics`. I’m not 100% that this could work without the solved plugin installed, but it could be worth a check?

If you run a query in [data explorer](https://meta.discourse.org/t/32566?silent=true) to grab them all, delete one, and run the query again to see if it’s disappeared, that could be an easy way to see if it could work?

Restoring the topic doesn’t restore the record in `discourse_solved_solved_topics`, so (potentially 🙂) a quick ‘delete and restore’ could clear them out. 🤞

---

<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: [December 20, 2025, 9:59pm UTC](https://meta.discourse.org/t/discourse-solved-solved-topics-violates-not-null-constraint-during-rebuild/391813/4 "2025-12-20T21:59:17Z")

</div>

> [@JammyDodger](#):
>
> I’m not 100% that this could work without the solved plugin installed, but it could be worth a check?

I’m fairly certain that it won’t since the code that does that is in the plugin.

I’m also fairly certain that the database is broken. It’s not supposed to have newlines in that value column. Deleting them from the database is what needs to happen. If you don’t, you’ll forget when you try to move to a new server and restore this database (and it’ll have solved because it’s in core) and you’ll have to figure this out all over again.

---

<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: [December 20, 2025, 10:09pm UTC](https://meta.discourse.org/t/discourse-solved-solved-topics-violates-not-null-constraint-during-rebuild/391813/5 "2025-12-20T22:09:29Z")

</div>

Ah, thought it might be a longshot. I wasn’t sure where the cleanup was kept. 🙂

Looks like Alexander had a similar issue and went the DB route: [Error upgrading to latest Discourse -- solved - #4 by Alexander\_Wright](https://meta.discourse.org/t/error-upgrading-to-latest-discourse-solved/362519/4)

---

<div class="post-metadata">

### Author: ![Steven](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/steven/32/187890_2.png) [@Steven](https://meta.discourse.org/u/Steven)
#### Post date: [December 21, 2025, 7:03am UTC](https://meta.discourse.org/t/discourse-solved-solved-topics-violates-not-null-constraint-during-rebuild/391813/6 "2025-12-21T07:03:12Z")

</div>

Thanks @pfaffman and @JammyDodger, I’ll dig in the db to try to fix this.

With [data explorer](https://meta.discourse.org/t/32566?silent=true), I have the list of problematic rows, we can see this is very limited in time, maybe a bit of an issue with the plugin during that time?

 ![image](https://global.discourse-cdn.com/meta/original/4X/a/a/3/aa39d0a02901fad942a6b0631c6dc03e5bd12ee8.png)

I’ve seen this commit that tried to fix a similar issue?

> <https://github.com/discourse/discourse-solved/commit/1805184cde87d2621f1252612f142f4bbbf03a79>
>
> We are seeing some errors when migrating and adding indexes on \`answer\_post\_id\`.…
> 
> \`\`\`
> \#\<StandardError:"An error has occurred, all later migrations canceled:\\n\\nPG::UniqueViolation: ERROR: could not create unique index \\"index\_discourse\_solved\_solved\_topics\_on\_answer\_post\_id\\"\\nDETAIL: Key (answer\_post\_id)=(13006) is duplicated.\\n"\>
> \`\`\`
> 
> This PR modifies the earlier migration, and also adds one before the addition of indexes to remove duplicates.

Interesting anyway. I’ll try to fix this, I’ll take my time since it’s very sensible

---

<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: [December 21, 2025, 11:49am UTC](https://meta.discourse.org/t/discourse-solved-solved-topics-violates-not-null-constraint-during-rebuild/391813/7 "2025-12-21T11:49:18Z")

</div>

It should be pretty easy to get [Ask.discourse.com](http://Ask.discourse.com) to give you a query that will find all of the ones you want to delete and (after you’ve seen that part of the query works) delete them all.

---

<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: [December 21, 2025, 12:56pm UTC](https://meta.discourse.org/t/discourse-solved-solved-topics-violates-not-null-constraint-during-rebuild/391813/8 "2025-12-21T12:56:49Z")

</div>

Having the system user as the one who marked solved is a bit unusual in there too. I think that was also the same for Alexander, looking at his error.

With two similar reports, do you think this could be a case of the migration missing an edge case, @pfaffman?

---

<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: [December 21, 2025, 1:56pm UTC](https://meta.discourse.org/t/discourse-solved-solved-topics-violates-not-null-constraint-during-rebuild/391813/9 "2025-12-21T13:56:38Z")

</div>

> [@JammyDodger](#):
>
> do you think this could be a case of the migration missing an edge case, @pfaffman?

I wouldn’t hazard a guess.

---

<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: [December 21, 2025, 2:19pm UTC](https://meta.discourse.org/t/discourse-solved-solved-topics-violates-not-null-constraint-during-rebuild/391813/10 "2025-12-21T14:19:31Z")

</div>

I suppose two in eight months isn’t exactly a flood, so perhaps not enough to dig deeper. 🙂

> [@Steven](#):
>
> we can see this is very limited in time, maybe a bit of an issue with the plugin during that time?

It looks like the other report has a similar date range too:

> [@Error upgrading to latest Discourse -- solved](https://meta.discourse.org/t/error-upgrading-to-latest-discourse-solved/362519/3):
>
> `DETAIL: Failing row contains (1152, 16673, null, -1, null, 2021-05-10 18:32:53.008822, 2021-05-10 18:32:53.008822)`

Not hugely useful to know for the task in hand, but possibly helpful if more reports come in.
