{"record":{"id":"73f319c8a318c4dc","repo":"RocketChat/Rocket.Chat","slug":"error-no-messages","errorCode":"error-no-messages","errorMessage":"No messages found","messagePattern":"No messages found","errorType":"exception","errorClass":"Meteor.Error","httpStatus":400,"severity":"warning","filePath":"apps/meteor/server/api/v1/im.ts","lineNumber":827,"sourceCode":"\t\tif (!room || room?.t !== 'd') {\n\t\t\tthrow new Meteor.Error('error-room-not-found', `No direct message room found by the id of: ${roomId}`);\n\t\t}\n\n\t\tconst { offset, count } = await getPaginationItems(this.queryParams);\n\t\tconst { sort, fields, query } = await this.parseJsonQuery();\n\t\tconst ourQuery = Object.assign({}, query, { rid: room._id });\n\n\t\tconst { cursor, totalCount } = Messages.findPaginated<IMessage>(ourQuery, {\n\t\t\tsort: sort || { ts: -1 },\n\t\t\tskip: offset,\n\t\t\tlimit: count,\n\t\t\tprojection: fields,\n\t\t});\n\n\t\tconst [msgs, total] = await Promise.all([cursor.toArray(), totalCount]);\n\n\t\tif (!msgs) {\n\t\t\tthrow new Meteor.Error('error-no-messages', 'No messages found');\n\t\t}\n\n\t\treturn API.v1.success({\n\t\t\tmessages: await normalizeMessagesForUser(msgs, this.userId),\n\t\t\toffset,\n\t\t\tcount: msgs.length,\n\t\t\ttotal,\n\t\t});\n\t};\n\nconst dmListEndpointsProps = {\n\tauthRequired: true as const,\n\tresponse: {\n\t\t200: paginatedImsResponseSchema,\n\t\t400: validateBadRequestErrorResponse,\n\t\t401: validateUnauthorizedErrorResponse,\n\t},\n};","sourceCodeStart":809,"sourceCodeEnd":845,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/e4b8178b205510181a96ceefee043d0abcd13e5a/apps/meteor/server/api/v1/im.ts#L809-L845","documentation":"Intended to signal that im.messages.others found no messages (im.ts:821), but the check is if (!msgs) on the result of cursor.toArray() from findPaginated. toArray() always resolves to an array and empty arrays are truthy, so on a stock server this error is unreachable: a DM with zero messages returns 200 with messages: [] and total: 0. It is effectively dead code kept from an older implementation.","triggerScenarios":"Only a driver-level failure that resolves toArray() to a falsy value could trigger it; a normal empty room or an out-of-range offset never does.","commonSituations":"Developers reading the throw site and writing dedicated handlers for error-no-messages; tests asserting a 400 on empty rooms that then see 200 + [] instead.","solutions":["Handle 200 with messages: [] (or total: 0) as the no-messages case, not an error","If you genuinely receive this error, suspect a customized/forked build - report it against the upstream repo"],"exampleFix":"// before (wrong assumption)\n const res = await api.get('/api/v1/im.messages.others', { params: { roomId } });\n if (res.error) handleEmpty(); // never happens for empty rooms\n\n // after\n const { messages, total } = await api.get('/api/v1/im.messages.others', { params: { roomId } });\n if (!messages?.length) handleEmpty(); // correct empty handling","handlingStrategy":"fallback","validationCode":"const { messages, total } = await api.get('/api/v1/im.messages.others', { params: { roomId } });\nconst isEmpty = !Array.isArray(messages) || messages.length === 0 || total === 0;\nif (isEmpty) renderEmptyState();","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Base empty-collection handling on the response payload (messages.length / total), never on an error","Read the endpoint's declared 200 schema rather than inferring behavior from throw sites"],"tags":["rest-api","messages","dead-code","pagination"],"backgroundTag":"empty-result-handling","analyzedSha":"e4b8178b205510181a96ceefee043d0abcd13e5a","analyzedAt":"2026-08-18T15:26:39.429Z","contentChangedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}