{"record":{"id":"6b503de3dda3d01d","repo":"RocketChat/Rocket.Chat","slug":"error-room-param-not-provided-6b503d","errorCode":"error-room-param-not-provided","errorMessage":"Query param \"roomId\" or \"username\" is required","messagePattern":"Query param \"roomId\" or \"username\" is required","errorType":"exception","errorClass":"Meteor.Error","httpStatus":400,"severity":"warning","filePath":"apps/meteor/server/api/v1/im.ts","lineNumber":51,"sourceCode":"import { getChannelHistory } from '../../meteor-methods/messages/getChannelHistory';\nimport { hideRoomMethod } from '../../meteor-methods/rooms/hideRoom';\nimport { leaveRoomMethod } from '../../meteor-methods/rooms/leaveRoom';\nimport { saveRoomSettings } from '../../meteor-methods/rooms/saveRoomSettings';\nimport { settings } from '../../settings';\nimport type { ExtractRoutesFromAPI } from '../ApiClass';\nimport { API } from '../api';\nimport type { TypedAction } from '../definition';\nimport { addUserToFileObj } from '../lib/addUserToFileObj';\nimport { composeRoomWithLastMessage } from '../lib/composeRoomWithLastMessage';\nimport { getPaginationItems } from '../lib/getPaginationItems';\n\nconst findDirectMessageRoom = async (\n\tkeys: { roomId?: string; username?: string },\n\tuid: string,\n): Promise<{ room: IRoom; subscription: ISubscription | null }> => {\n\tconst nameOrId = 'roomId' in keys ? keys.roomId : keys.username;\n\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}","sourceCodeStart":33,"sourceCodeEnd":69,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/f9d3ec372bb580fa8d036f94cf03925a478ef768/apps/meteor/server/api/v1/im.ts#L33-L69","documentation":"Thrown by the findDirectMessageRoom helper in im.ts (lines 49-52) which backs the im.* DM endpoints. The helper picks roomId if the key is present, otherwise username; if the resulting value is not a string (i.e. neither roomId nor username was supplied, or it was undefined), it rejects with error-room-param-not-provided. This is a client input error: a DM target was not provided at all.","triggerScenarios":"Calling any im.* endpoint routed through findDirectMessageRoom (e.g. im.info, im.files, im.history variants) without both roomId and username in the query/body, so nameOrId resolves to undefined.","commonSituations":"A client opens a DM screen before the counterpart is selected (username undefined) and before a roomId exists. A bot calls im.* with neither identifier. Query string built from null variables.","solutions":["Always supply roomId (preferred for existing DMs) or username (to resolve/create the DM) on im.* calls.","Guard the call site: skip the request when neither identifier is available.","Use username when creating/opening a DM by counterpart; use roomId for subsequent operations.","Confirm the field is named exactly 'roomId' or 'username'."],"exampleFix":"// before\nawait GET('/api/v1/im.info', {}); // no roomId/username -> error-room-param-not-provided\n\n// after\nconst target = roomId ?? `@${username}`;\nawait GET('/api/v1/im.info', roomId ? { roomId } : { username });","handlingStrategy":"validation","validationCode":"// Require a non-empty DM target before calling im.* endpoints.\nconst target = {};\nif (typeof roomId === 'string' && roomId.trim()) target.roomId = roomId;\nelse if (typeof username === 'string' && username.trim()) target.username = username;\nelse throw new Error('roomId or username is required');\nawait api.get('/api/v1/im.info', target);","typeGuard":"function hasDmTarget(p) {\n  return (typeof p?.roomId === 'string' && p.roomId.trim() !== '') ||\n         (typeof p?.username === 'string' && p.username.trim() !== '');\n}","tryCatchPattern":"try {\n  await api.get('/api/v1/im.info', target);\n} catch (e) {\n  if (isMeteorError(e) && e.reason === 'error-room-param-not-provided') {\n    showFormError('Select a contact first');\n    return;\n  }\n  throw e;\n}","preventionTips":["Disable DM-detail controls until a counterpart or roomId is chosen.","Use username to open/create a DM, roomId for subsequent operations.","Confirm exact field names roomId/username.","Unit-test im.* with neither identifier supplied."],"tags":["rest-api","im","direct-message","validation","input-validation"],"backgroundTag":null,"analyzedSha":"f9d3ec372bb580fa8d036f94cf03925a478ef768","analyzedAt":"2026-08-12T19:07:17.372Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}