RocketChat/Rocket.Chat · error · Meteor.Error
error-room-does-not-exist
error-room-does-not-exist
Error message
This room does not exist
What it means
Thrown by POST chat.readThread (apps/meteor/server/api/v1/chat.ts:298) when the thread's parent message exists (tmid resolved to an rid) but Rooms.findOneById(thread.rid) returns null. The thread points at a room record that no longer exists in the database, so there is no room to mark read. This is a data-integrity condition: the message survived while its room was deleted.
Solutions
- Treat as a permanent 404: remove the local unread/thread state for that tmid and stop calling readThread for it.
- Sanity-check the room with GET /api/v1/rooms.info?roomId=<rid> (from chat.getMessage's response) before marking read.
- If you administer the workspace, purge the orphaned message(s) with rid pointing to the deleted room so the data is consistent again.
- If you believe the room should still exist, inspect the Rooms collection for the id and restore/recreate the room.
Defensive patterns
Strategy: try-catch
Validate before calling
const msg = await rc.get('/api/v1/chat.getMessage', { params: { msgId: tmid } });
const room = await rc.get('/api/v1/rooms.info', { params: { roomId: msg.message.rid } });
if (!room?.room) throw new Error('thread room missing'); Try / catch
try {
await rc.post('/api/v1/chat.readThread', { tmid });
} catch (e) {
if (e?.errorType === 'error-room-does-not-exist') dropOrphanThread(tmid); // permanent, do not retry
else throw e;
} Prevention
- Periodically reconcile cached threads against live rooms; orphaned parents indicate retention or cleanup gaps.
- If you operate the server, investigate why Messages outlived their Rooms (partial restore, buggy erase job).
When it happens
Trigger: POST /api/v1/chat.readThread with a valid tmid whose room was deleted (cascade cleanup missed the message), typically after a room was removed while messages with that rid remained, or in workspaces restored from partial backups where the Messages collection is newer than Rooms.
Common situations: Retention/erase jobs that delete rooms but leave orphan thread parents; workspace migrations or backup restores with collection drift; test fixtures seeded with messages but no matching room documents.
Related errors
- error-invalid-message
- error-not-allowed
- The required "mid" body param is missing.
- Cannot send system messages using 'chat.sendMessage'
- error-emoji-param-not-provided
AI-assisted analysis of RocketChat/Rocket.Chat@e4b8178b20 (2026-08-18).
Data as JSON: /api/errors/e15c6deac2ebd772.
Report an issue: GitHub.
Appendix: source
Thrown at apps/meteor/server/api/v1/chat.ts:302
async function action() {
if (!settings.get<boolean>('Threads_enabled')) {
throw new Meteor.Error('error-not-allowed', 'Threads Disabled');
}
const { tmid } = this.bodyParams;
const thread = await Messages.findOneById(tmid, { projection: { rid: 1 } });
if (!thread?.rid) {
throw new Meteor.Error('error-invalid-message', 'Invalid Message');
}
const [user, room] = await Promise.all([
Users.findOneById(this.userId),
Rooms.findOneById(thread.rid, { projection: { ...roomAccessAttributes, t: 1, _id: 1 } }),
]);
if (!room) {
throw new Meteor.Error('error-room-does-not-exist', 'This room does not exist');
}
if (!user || !(await canAccessRoomAsync(room, user))) {
throw new Meteor.Error('error-not-allowed', 'Not Allowed');
}
await callbacks.run('beforeReadMessages', room._id, user._id);
await readThread({ user, room, tmid });
return API.v1.success();
},
)
.post(
'chat.update',
{
authRequired: true,
body: isChatUpdateProps,
response: {View on GitHub (pinned to e4b8178b20)