rooms: a destroyed room's row stays as if nothing happened #95

Open
opened 2026-11-08 00:13:18 +00:00 by asxpi · 2 comments
Member

Summary

When a room is destroyed, by us as its owner or by another owner, its row stays in the room list as if nothing had happened. The room is gone, we are no longer in it, and nothing on the row says so. Found by hand with anotherim-js develop (009c9884, XML_LOG=1).

Steps

  1. Create a room (Join room… with a new address), then room details → ⋮ → Destroy room… → Destroy.
  2. The server confirms (<presence type='unavailable'> with <destroy/>), and libtacky emits muc <Destroyed>.
  3. The row is still in the list: same name, no state, and opening it shows an empty room we are not in.

Why

ui/src/state/muc-room.ts:204 reacts to Destroyed only with this.#clear(), which empties the room's state. The row itself comes from the XEP-0402 bookmark, which nothing removes. Today libtacky also keeps the bookmark with autojoin='true' and recreates the room on the next sign-in. That part is libtacky's to fix: another-im/libtacky#26, with a fix in another-im/libtacky#27, where the bookmark is taken back on destroy and autojoin skips a room that does not exist.

Suggestion

On muc <Destroyed> ({acc, jid, altRoom?, reason?}):

  • Mark the row as destroyed, e.g. greyed out with "Room destroyed", plus the reason when one is given. Keep the history readable.
  • Remove: one action that drops the row. Before the libtacky fix that means bookmarks remove; after it, the bookmark is already gone, so close the chat (chatlist close for the ?join chat).
  • Alternate venue: when altRoom is set (XEP-0045 §10.9, <destroy jid='…'/>), offer Join the new room with that address. Never join it automatically.
  • Join hint: a room whose bookmark shows room_state error "Room does not exist" (what libtacky reports with the fix when autojoin finds the room gone) gets the same mark and actions, plus Create again for an owner who means it (an explicit muc join still creates).
  • interop issue 1, comment "New: C34" (how it was found, with XML logs).
## Summary When a room is destroyed, by us as its owner or by another owner, its row stays in the room list as if nothing had happened. The room is gone, we are no longer in it, and nothing on the row says so. Found by hand with anotherim-js `develop` (`009c9884`, `XML_LOG=1`). ## Steps 1. Create a room (Join room… with a new address), then room details → ⋮ → **Destroy room…** → Destroy. 2. The server confirms (`<presence type='unavailable'>` with `<destroy/>`), and libtacky emits `muc <Destroyed>`. 3. The row is still in the list: same name, no state, and opening it shows an empty room we are not in. ## Why `ui/src/state/muc-room.ts:204` reacts to `Destroyed` only with `this.#clear()`, which empties the room's state. The row itself comes from the XEP-0402 bookmark, which nothing removes. Today libtacky also keeps the bookmark with `autojoin='true'` and recreates the room on the next sign-in. That part is libtacky's to fix: https://dev.another.im/another-im/libtacky/issues/26, with a fix in https://dev.another.im/another-im/libtacky/pulls/27, where the bookmark is taken back on destroy and autojoin skips a room that does not exist. ## Suggestion On `muc <Destroyed>` (`{acc, jid, altRoom?, reason?}`): - **Mark the row** as destroyed, e.g. greyed out with "Room destroyed", plus the `reason` when one is given. Keep the history readable. - **Remove**: one action that drops the row. Before the libtacky fix that means `bookmarks remove`; after it, the bookmark is already gone, so close the chat (`chatlist close` for the `?join` chat). - **Alternate venue**: when `altRoom` is set (XEP-0045 §10.9, `<destroy jid='…'/>`), offer **Join the new room** with that address. Never join it automatically. - **Join hint**: a room whose bookmark shows `room_state` `error` "Room does not exist" (what libtacky reports with the fix when autojoin finds the room gone) gets the same mark and actions, plus **Create again** for an owner who means it (an explicit `muc join` still creates). ## Related - interop issue 1, comment "New: C34" (how it was found, with XML logs).
Owner

Fixed in anotherim-js 0.8.0-rc8, built on libtacky 1.2.2: https://dev.another.im/another-im/anotherim-js/releases/tag/v0.8.0-rc8

A destroyed room's row now shows "This room was destroyed" in the header and in the row menu, the name struck through in the list, and Remove over the composer (plus "Go to the new room" when the owner named one) in place of Join. A room found gone at sign-in says so too and is not made again.

Fixed in anotherim-js 0.8.0-rc8, built on libtacky 1.2.2: https://dev.another.im/another-im/anotherim-js/releases/tag/v0.8.0-rc8 A destroyed room's row now shows "This room was destroyed" in the header and in the row menu, the name struck through in the list, and Remove over the composer (plus "Go to the new room" when the owner named one) in place of Join. A room found gone at sign-in says so too and is not made again.
Author
Member

Still seen in 0.8.0-rc9 (142ee094, libtacky v1.2.3), which contains b50f1ae3 and rc8: after the owner destroys a room from the room menu, nothing in the UI says it was destroyed. Recorded on all three test servers in the interop GUI VM runs (2026-11-09).

Expected (b50f1ae3, state/destroyed-rooms.ts): on muc <Destroyed> the header says "This room was destroyed", the composer is disabled with Remove over it, the row's name is struck through.

Seen right after the destroy: the chat shows "Not joined", the composer is enabled, the name is not struck through, there is no Remove. After a restart the row is gone, as designed (session-only state).

server run right after the destroy
anotherim-server 225948
ejabberd 26.09 194543
Prosody 13.0.7 194144

Noted in 5 runs' EVIDENCE.md (Prosody with Gajim, Dino and anotherim-web; anotherim-server with anotherim-web and Gajim); in run 225948 the harness also OCRs aim's room after the restart for Remove / "Go to the new room" / Join: none found (steps.log:150). On Prosody libtacky's autojoin-off republish is at client.log:289.

libtacky did its part. In the anotherim-server run (client.log:625-633):

  • L625 our <destroy/> iq, L631 the room's unavailable presence with <x xmlns='http://jabber.org/protocol/muc#user'><destroy/>;
  • L632 libtacky republishes the bookmark with autojoin='false'. That publish comes from bookmarks.tcl OnMucDestroyed, which is subscribed to muc:<Destroyed> (v1.2.3 bookmarks.tcl:129, :1465), so the <Destroyed> event was emitted.
  • After a restart aim does not rejoin or recreate the room (C34 fixed, steps.log).

So the break is between libtacky's muc <Destroyed> and the view: the event not reaching DestroyedRooms (store.backend.on('muc', 'Destroyed', …)) in the Tauri build, or the chat view/row not redrawing on it. Not traced further; the runs do not log host-side events.

Re-run: vms/tools/vmrun.zsh explore vms/examples/xep0045admin.py NAME gajim in the interop repo (each EVIDENCE.md has the exact command).

Still seen in 0.8.0-rc9 (`142ee094`, libtacky v1.2.3), which contains b50f1ae3 and rc8: after the owner destroys a room from the room menu, nothing in the UI says it was destroyed. Recorded on all three test servers in the interop GUI VM runs (2026-11-09). **Expected** (b50f1ae3, `state/destroyed-rooms.ts`): on `muc <Destroyed>` the header says "This room was destroyed", the composer is disabled with Remove over it, the row's name is struck through. **Seen** right after the destroy: the chat shows "Not joined", the composer is enabled, the name is not struck through, there is no Remove. After a restart the row is gone, as designed (session-only state). | server | run | right after the destroy | |---|---|---| | anotherim-server | [225948](https://dev.another.im/another-im/interop/src/commit/ae9919db6458281e095bfbd16b4e678835993752/runs/20261109-225948-XEP-0045-aim-vs-gajim-anotherim-server/EVIDENCE.md) | ![](https://dev.another.im/another-im/interop/media/commit/ae9919db6458281e095bfbd16b4e678835993752/runs/20261109-225948-XEP-0045-aim-vs-gajim-anotherim-server/shot-11-aim-destroyed.png) | | ejabberd 26.09 | [194543](https://dev.another.im/another-im/interop/src/commit/ae9919db6458281e095bfbd16b4e678835993752/runs/20261109-194543-XEP-0045-aim-vs-gajim-ejabberd/EVIDENCE.md) | ![](https://dev.another.im/another-im/interop/media/commit/ae9919db6458281e095bfbd16b4e678835993752/runs/20261109-194543-XEP-0045-aim-vs-gajim-ejabberd/shot-11-aim-destroyed.png) | | Prosody 13.0.7 | [194144](https://dev.another.im/another-im/interop/src/commit/7d1cb92e81d5ae89612fc7bf9da5598ceec32ded/runs/20261109-194144-XEP-0045-aim-vs-gajim-prosody/EVIDENCE.md) | ![](https://dev.another.im/another-im/interop/media/commit/7d1cb92e81d5ae89612fc7bf9da5598ceec32ded/runs/20261109-194144-XEP-0045-aim-vs-gajim-prosody/shot-4-aim-destroyed.png) | Noted in 5 runs' EVIDENCE.md (Prosody with Gajim, Dino and anotherim-web; anotherim-server with anotherim-web and Gajim); in run 225948 the harness also OCRs aim's room after the restart for Remove / "Go to the new room" / Join: none found ([steps.log:150](https://dev.another.im/another-im/interop/src/commit/ae9919db6458281e095bfbd16b4e678835993752/runs/20261109-225948-XEP-0045-aim-vs-gajim-anotherim-server/steps.log#L150)). On Prosody libtacky's autojoin-off republish is at [client.log:289](https://dev.another.im/another-im/interop/src/commit/7d1cb92e81d5ae89612fc7bf9da5598ceec32ded/runs/20261109-194144-XEP-0045-aim-vs-gajim-prosody/client.log#L289). **libtacky did its part.** In the anotherim-server run ([client.log:625-633](https://dev.another.im/another-im/interop/src/commit/ae9919db6458281e095bfbd16b4e678835993752/runs/20261109-225948-XEP-0045-aim-vs-gajim-anotherim-server/client.log#L625-L633)): - L625 our `<destroy/>` iq, L631 the room's unavailable presence with `<x xmlns='http://jabber.org/protocol/muc#user'><destroy/>`; - L632 libtacky republishes the bookmark with `autojoin='false'`. That publish comes from `bookmarks.tcl` `OnMucDestroyed`, which is subscribed to `muc:<Destroyed>` (v1.2.3 `bookmarks.tcl:129`, `:1465`), so the `<Destroyed>` event was emitted. - After a restart aim does not rejoin or recreate the room (C34 fixed, [steps.log](https://dev.another.im/another-im/interop/src/commit/ae9919db6458281e095bfbd16b4e678835993752/runs/20261109-225948-XEP-0045-aim-vs-gajim-anotherim-server/steps.log#L124)). So the break is between libtacky's `muc <Destroyed>` and the view: the event not reaching `DestroyedRooms` (`store.backend.on('muc', 'Destroyed', …)`) in the Tauri build, or the chat view/row not redrawing on it. Not traced further; the runs do not log host-side events. Re-run: `vms/tools/vmrun.zsh explore vms/examples/xep0045admin.py NAME gajim` in the interop repo (each EVIDENCE.md has the exact command).
Sign in to join this conversation.
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
another-im/anotherim-js#95
No description provided.