RocketChat/Rocket.Chat · error · Meteor.Error
error-room-not-found
error-room-not-found
Error message
The required "roomId" param provided does not match any direct message
What it means
Thrown by the shared findDirectMessageRoom helper when the room resolved from roomId/username is either missing or not of type 'd'. The lookup uses getRoomByNameOrIdWithOptionToJoin with type:'d', then re-checks room.t === 'd'. This single guard backs most im.* endpoints (close, delete, setTopic, counters, files, members, messages, history, blockUser), so it is the most common im API failure.
Source
Thrown at apps/meteor/server/api/v1/im.ts:68
if (typeof nameOrId !== 'string') {
throw new Meteor.Error('error-room-param-not-provided', 'Query param "roomId" or "username" is required');
}
const user = await Users.findOneById(uid);
if (!user) {
throw new Meteor.Error('error-invalid-user', 'Invalid user', {
method: 'findDirectMessageRoom',
});
}
const room = await getRoomByNameOrIdWithOptionToJoin({
user,
nameOrId,
type: 'd',
});
if (!room || room?.t !== 'd') {
throw new Meteor.Error('error-room-not-found', 'The required "roomId" param provided does not match any direct message');
}
const subscription = await Subscriptions.findOne({ 'rid': room._id, 'u._id': uid });
return {
room,
subscription,
};
};
type DmDeleteProps =
| {
roomId: string;
}
| {
username: string;
};
View on GitHub (pinned to f9d3ec372b)
Solutions
- Verify the value is a real DM rid by calling rooms.info or im.list before the operation.
- If resolving by username, confirm the username is correct and that a DM exists (im.create.open with that username first).
- Make sure you are not passing a #channel or group rid into an im.* endpoint.
- Refresh the roomId from im.list after a workspace event that may have removed the DM.
Example fix
// before
await POST /api/v1/im.close { roomId: 'GENERAL' } // a channel rid
// after
const dm = await POST /api/v1/im.create { username: 'bob' };
await POST /api/v1/im.close { roomId: dm.room.rid }; Defensive patterns
Strategy: validation
Validate before calling
// Resolve and type-check the DM before any mutating im.* call
async function assertDmExists(api, ridOrName) {
const res = await api.get('/api/v1/rooms.info', { params: { roomId: ridOrName } });
if (res.data.room.t !== 'd') {
throw new Error(`Expected a direct message, got room type ${res.data.room.t}`);
}
return res.data.room; // ._id is the canonical rid
} Type guard
function isDirectMessageRoom(room: unknown): room is { _id: string; t: 'd' } {
return typeof room === 'object' && room !== null
&& (room as any).t === 'd'
&& typeof (room as any)._id === 'string';
} Try / catch
try {
await api.post('/api/v1/im.close', { roomId });
} catch (e) {
if (e.response?.data?.error === 'error-room-not-found') {
// refresh rid from im.list and either retry once or give up
} else throw e;
} Prevention
- Always source roomId from im.list or im.create, never hard-code.
- Treat the rid as ephemeral; re-fetch after workspace events that remove DMs.
- Never feed a channel/group rid into an im.* endpoint.
When it happens
Trigger: Calling any im.* endpoint that delegates to findDirectMessageRoom with a roomId that does not exist, that exists but is a channel/group rather than a DM, or a username that has no DM with the calling user. Also when the DM was deleted between resolution and the call.
Common situations: Client holds a stale roomId after the DM was closed/erased; passing a channel rid into an im endpoint by mistake; username typo when resolving by username; the DM target user was deactivated and the room pruned.
Related errors
- error-roomid-param-not-provided
- error-invalid-room
- Invalid Api parameter provided, it must be a valid IApi obje
- error-emoji-param-not-provided
- error-param-required
AI-assisted analysis of RocketChat/Rocket.Chat@f9d3ec372b (2026-08-12).
Data as JSON: /api/errors/0630256c82ace490.
Report an issue: GitHub.