Remap failure when changing discourse domain

AI-generated summary

fpoulain encountered a remap failure while changing their Discourse domain from plop.domain.fr to forum.plop.fr, due to a PostgreSQL unique constraint violation: duplicate key value violates unique constraint "unique_post_links". The error occurred because the new domain (forum.plop.fr) was already referenced in topic links, likely from prior forum discussions. The official guide (Change the domain name or rename your Discourse) didn’t anticipate this edge case. To resolve it, fpoulain manually edited the topic_links table via PostgreSQL, temporarily appending a trailing slash (/) to avoid duplicates, then successfully ran the remap command. Afterward, they manually reviewed and corrected affected topics (e.g., topic ID 274) for content consistency. In a follow-up post fpoulain suggests that the documentation could be improved by recommending a preliminary remap to a placeholder domain (e.g., talk.foo-or-bar-that-s-the-question.com) to clear old references before the final remap, though they did not test this workaround.

Hi,
I tried to change a discourse domain name, following Change the domain name or rename your Discourse. Things looked right until I launched the command

discourse remap talk.foo.com talk.bar.com

I got the following:

root@plop:/var/www/discourse# discourse remap plop.domain.fr forum.plop.fr
Rewriting all occurrences of plop.domain.fr to forum.plop.fr
THIS TASK WILL REWRITE DATA, ARE YOU SURE (type YES)
YES
backup_metadata=1
email_logs=991
javascript_caches=1
post_revisions=126
post_search_data=20
posts=782
stylesheet_cache=446
theme_settings=1
Error: ERROR:  duplicate key value violates unique constraint "unique_post_links"
DETAIL:  Key (topic_id, post_id, url)=(274, 455, http://forum.plop.fr) already exists.
The remap has only been partially applied due to the error above. Please re-run the script again.

It seemed it looked like to the error reported here, but was slightly different. I guess the bug is related to the fact that the new domain has been discussed on the forum.

To overcome it, I was unable to launch something like db:exec to force db commands via rake. So I did it directly via postgres:

  1. connect the dababase:
# cd /var/discourse/
# ./launcher enter app
# su - postgres
$ psql
postgres=# \c discourse
  1. try to directly replace url in the table
discourse=# update topic_links set url=REPLACE(url, 'plop.domain.fr', 'forum.plop.fr');
ERROR:  duplicate key value violates unique constraint "unique_post_links"
DETAIL:  Key (topic_id, post_id, url)=(274, 455, http://forum.plop.fr) already exists.
  1. on error : force a replacement that don’t break unicity, e.g. forum.plop.fr/:
discourse=# update topic_links set url=REPLACE(url, 'plop.domain.fr', 'forum.plop.fr/') where topic_id=274;
  1. repeat 3. until 2. finishes without error. Then quit pg.
discourse=# update topic_links set url=REPLACE(url, 'plop.domain.fr', 'forum.plop.fr');
UPDATE 1349
discourse=# 
\q
  1. relaunch the remap and the rebake:
$ exit
# discourse remap plop.domain.fr forum.plop.fr
  1. Manually check and correct the problematic topics (which content may be inconsistent), by visiting forum.plop.fr/t/topic/274 and others.

If I correctly understand the problem a posteriori, the doc could suggest to remove all old occurrences of talk.bar.com prior to launch this command. It could simply done via

discourse remap talk.bar.com talk.foo-or-bar-that-s-the-question.com

(I didn’t tried.)