{"record":{"id":"d9d0713aad99139d","repo":"RocketChat/Rocket.Chat","slug":"error-room-not-found-d9d071","errorCode":"error-room-not-found","errorMessage":"The required \"roomId\" or \"roomName\" param provided does not match any group","messagePattern":"The required \"roomId\" or \"roomName\" param provided does not match any group","errorType":"exception","errorClass":"Meteor.Error","httpStatus":null,"severity":"error","filePath":"apps/meteor/server/api/v1/groups.ts","lineNumber":99,"sourceCode":"\t\t\tname: 1,\n\t\t\tfname: 1,\n\t\t\tprid: 1,\n\t\t\tarchived: 1,\n\t\t\tbroadcast: 1,\n\t\t},\n\t};\n\n\tconst room = await (() => {\n\t\tif ('roomId' in params) {\n\t\t\treturn Rooms.findOneById(params.roomId || '', roomOptions);\n\t\t}\n\t\tif ('roomName' in params) {\n\t\t\treturn Rooms.findOneByName(params.roomName || '', roomOptions);\n\t\t}\n\t})();\n\n\tif (room?.t !== 'p') {\n\t\tthrow new Meteor.Error('error-room-not-found', 'The required \"roomId\" or \"roomName\" param provided does not match any group');\n\t}\n\n\treturn room;\n}\n\n// Returns the private group subscription IF found otherwise it will return the failure of why it didn't. Check the `statusCode` property\nasync function findPrivateGroupByIdOrName({\n\tparams,\n\tcheckedArchived = true,\n\tuserId,\n}: {\n\tparams:\n\t\t| {\n\t\t\t\troomId?: string;\n\t\t  }\n\t\t| {\n\t\t\t\troomName?: string;\n\t\t  };","sourceCodeStart":81,"sourceCodeEnd":117,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/f9d3ec372bb580fa8d036f94cf03925a478ef768/apps/meteor/server/api/v1/groups.ts#L81-L117","documentation":"Thrown by getRoomFromParams when the looked-up room does not exist OR exists but its type is not 'p' (private group). Because the helper is used only by groups.* endpoints, passing a channel ('c'), direct message ('d'), or team-public room triggers it EVEN THOUGH the room exists. So 'not found' effectively means 'not a private group'.","triggerScenarios":"Passing a channel id/name to groups.info; passing a DM id; roomName of a public room; a non-existent id; a room whose type was changed away from 'p'.","commonSituations":"Using the groups.* endpoint for a channel (should use channels.*); typo in the identifier; room converted from private to public.","solutions":["Use the channels.* endpoints for type 'c' rooms and the im.* endpoints for DMs.","Confirm the target room is actually a private group before calling groups.*.","Verify the id/name spelling and that the room still exists."],"exampleFix":"// before\nconst url = `/api/v1/groups.info?roomName=${name}`; // name may be a channel\n// after\n// look up the room first or branch on its type\nconst endpoint = room.t === 'c' ? 'channels.info' : room.t === 'p' ? 'groups.info' : 'im.info';\nconst url = `/api/v1/${endpoint}?roomId=${encodeURIComponent(room._id)}`;","handlingStrategy":"type-guard","validationCode":"// route to the correct endpoint family based on room type\nfunction endpointFor(room) {\n  switch (room.t) {\n    case 'p': return 'groups';\n    case 'c': return 'channels';\n    case 'd': return 'im';\n    default: throw new Error('unsupported room type');\n  }\n}","typeGuard":"function isPrivateGroup(room): room is { _id: string; t: 'p' } {\n  return !!room && room.t === 'p';\n}","tryCatchPattern":"try { await groupsInfo({ roomId }); }\ncatch (e) {\n  if (isApiError(e, 'error-room-not-found')) { /* maybe a channel: retry via channels.info, else show not-found */) }\n  else throw e;\n}","preventionTips":["Check room.t before choosing groups.* vs channels.* vs im.*.","Remember groups.* strictly requires type 'p'.","Handle 'error-room-not-found' by re-routing to the endpoint matching the actual room type."],"tags":["groups","validation","rest-api","rooms"],"backgroundTag":null,"analyzedSha":"f9d3ec372bb580fa8d036f94cf03925a478ef768","analyzedAt":"2026-08-12T19:07:17.372Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}