Attempt to recreate deleted chat channel with the same name (still) fails

Continuing the discussion from Attempt to recreate deleted chat channel with same name fails:

This bug was reported in the linked thread but seems to still persist for me. I’m on latest and did a git pull and launcher rebuild yesterday.

When trying to name a new chat channel after any previously used chat channel name, there is a 500 error in the JS console.

In the Discourse error logs I get

Failed to handle exception in exception app middleware : ActiveRecord::RecordNotUnique : PG::UniqueViolation: ERROR:  duplicate key value violates unique constraint "index_chat_channels_on_slug"
DETAIL:  Key (slug)=(sec-fhir) already exists.

In the Rails console I can see that the deleted ChatChannels have gone, but I suspect somewhere the deleted slug remains in an index or in some other DB dependency and hasn’t been deleted.

This workaround doesn’t work for me, upon trying to rename “foo2” to “foo” I get the same 500 error, because of the failed uniqueness constraint on the slug.

I’m not sure how to safely delete the (indexed?) slugs of deleted ChatChannels, but I’d be willing to have a go.


Possibly related: this issue which also affects slugs, but it doesn’t seem to be the same issue: Attempt to recreate deleted chat channel with same name fails

1 Like

I just tested the following now and had no issue:

  1. Create channel with name “whiskers” and slug “whiskers”
  2. Delete channel
  3. Create channel with name “whiskers” and slug “whiskers”

That worked.

When the channel is deleted (step 2), the slug is automatically changed to something unique. But since you deleted your channel prior to that change being introduced, the old slug may be still hanging around.

You can probably manually update the slug for the deleted channel via the rails console, but I’m not sure what the right incantation is. I’ll ask around.

Note also, that channel slugs are now able to be edited independently of the channel name, so as a workaround, you could also make a channel with the desired name today and choose a different slug that doesn’t conflict.

2 Likes

This is super unexpected.

We don’t delete channels, we only soft delete them. So they should still be here with the deleted_at column filled.

If you run this in your console, you get no results?

ChatChannel.find_by(slug: "sec-fhir")
[1] pry(main)> ChatChannel.find_by(slug: "sec-fhir")
=> nil

I can confirm that this test also works for me on my instance, which is fully up to date.

I think the issue is that somewhere in the DB there is some slug hanging around that should have been deleted, which wasn’t, maybe there was a bug in a previous version which is now fixed. Chat has only been enabled on this instance for 17 days, so any bug would have to have been active in that time-frame.

Can’t repro this in any way. After doing a DB backup maybe you can try these in the rails console. Seems surprising though.

[1] pry(main)> DB.exec("DROP INDEX IF EXISTS index_chat_channels_on_slug;")
[2] pry(main)> DB.exec("CREATE UNIQUE INDEX index_chat_channels_on_slug ON chat_channels(slug);")

I checked and this is actually expected, since we exclude records with deleted_at filled in even with find_by:

ChatChannel.find_by(slug: "sec-fhir")
  ChatChannel Load (0.4ms)  SELECT "chat_channels".* FROM "chat_channels" WHERE "chat_channels"."deleted_at" IS NULL AND "chat_channels"."slug" = 'sec-fhir' LIMIT 1
=> nil

You will need to do this instead (adding with_deleted):

ChatChannel.with_deleted.find_by(slug: "sec-fhir")
  ChatChannel Load (0.3ms)  SELECT "chat_channels".* FROM "chat_channels" WHERE "chat_channels"."slug" = 'sec-fhir' LIMIT 1
=> #<CategoryChannel:0x00007fc9bfb4abf0
 id: 124,
 chatable_id: 19,
 deleted_at: Wed, 15 Feb 2023 01:19:20.982181000 UTC +00:00,
 deleted_by_id: nil,
 featured_in_category_id: nil,
 delete_after_seconds: nil,
 chatable_type: "Category",
 created_at: Fri, 13 Jan 2023 01:46:43.730329000 UTC +00:00,
 updated_at: Wed, 15 Feb 2023 01:19:56.427647000 UTC +00:00,
 name: "test channel",
 description: "",
 status: "archived",
 user_count: 1,
 last_message_sent_at: Fri, 13 Jan 2023 01:46:51.130903000 UTC +00:00,
 auto_join_users: false,
 user_count_stale: false,
 slug: "sec-fhir",
 type: "CategoryChannel",
 allow_channel_wide_mentions: true,
 messages_count: 0,
 threading_enabled: false>

So to clear out the old deleted channel slug do something like this:

channel = ChatChannel.with_deleted.find_by(slug: "sec-fhir")
channel.update!(slug: "#{channel.deleted_at.strftime("%Y%m%d-%H%M")}-#{channel.slug}-deleted")

Maybe we need a migration to fix these @mcwumbly and @joffreyjaffeux ?

2 Likes

Oh yes right forgot the with_deleted in this case :+1:

I suggest we just let your answer here for now. Should be a rare case: deleted before fix + wants to re-create with same name.

3 Likes

Thanks for the above. I didn’t know about with_deleted but that enabled me to see the deleted instances and to rename their slugs as per your snippet.

I can confirm this is fixed. I would agree with @joffreyjaffeux that this is not likely to be affecting many users so I’d say it’s enough that a Rails console fix is here in the thread.

3 Likes

Excellent, good to hear that resolved it for you Marcus. Closing off this topic now.

2 Likes