{"record":{"id":"0630256c82ace490","repo":"RocketChat/Rocket.Chat","slug":"error-room-not-found-063025","errorCode":"error-room-not-found","errorMessage":"The required \"roomId\" param provided does not match any direct message","messagePattern":"The required \"roomId\" param provided does not match any direct message","errorType":"exception","errorClass":"Meteor.Error","httpStatus":400,"severity":"error","filePath":"apps/meteor/server/api/v1/im.ts","lineNumber":68,"sourceCode":"\tif (typeof nameOrId !== 'string') {\n\t\tthrow new Meteor.Error('error-room-param-not-provided', 'Query param \"roomId\" or \"username\" is required');\n\t}\n\n\tconst user = await Users.findOneById(uid);\n\tif (!user) {\n\t\tthrow new Meteor.Error('error-invalid-user', 'Invalid user', {\n\t\t\tmethod: 'findDirectMessageRoom',\n\t\t});\n\t}\n\n\tconst room = await getRoomByNameOrIdWithOptionToJoin({\n\t\tuser,\n\t\tnameOrId,\n\t\ttype: 'd',\n\t});\n\n\tif (!room || room?.t !== 'd') {\n\t\tthrow new Meteor.Error('error-room-not-found', 'The required \"roomId\" param provided does not match any direct message');\n\t}\n\n\tconst subscription = await Subscriptions.findOne({ 'rid': room._id, 'u._id': uid });\n\n\treturn {\n\t\troom,\n\t\tsubscription,\n\t};\n};\n\ntype DmDeleteProps =\n\t| {\n\t\t\troomId: string;\n\t  }\n\t| {\n\t\t\tusername: string;\n\t  };\n","sourceCodeStart":50,"sourceCodeEnd":86,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/f9d3ec372bb580fa8d036f94cf03925a478ef768/apps/meteor/server/api/v1/im.ts#L50-L86","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nawait POST /api/v1/im.close { roomId: 'GENERAL' } // a channel rid\n\n// after\nconst dm = await POST /api/v1/im.create { username: 'bob' };\nawait POST /api/v1/im.close { roomId: dm.room.rid };","handlingStrategy":"validation","validationCode":"// Resolve and type-check the DM before any mutating im.* call\nasync function assertDmExists(api, ridOrName) {\n  const res = await api.get('/api/v1/rooms.info', { params: { roomId: ridOrName } });\n  if (res.data.room.t !== 'd') {\n    throw new Error(`Expected a direct message, got room type ${res.data.room.t}`);\n  }\n  return res.data.room; // ._id is the canonical rid\n}","typeGuard":"function isDirectMessageRoom(room: unknown): room is { _id: string; t: 'd' } {\n  return typeof room === 'object' && room !== null\n    && (room as any).t === 'd'\n    && typeof (room as any)._id === 'string';\n}","tryCatchPattern":"try {\n  await api.post('/api/v1/im.close', { roomId });\n} catch (e) {\n  if (e.response?.data?.error === 'error-room-not-found') {\n    // refresh rid from im.list and either retry once or give up\n  } else throw e;\n}","preventionTips":["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."],"tags":["direct-message","room-resolution","validation","api"],"backgroundTag":null,"analyzedSha":"f9d3ec372bb580fa8d036f94cf03925a478ef768","analyzedAt":"2026-08-12T19:07:17.372Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}