{"record":{"id":"0d7726f345325370","repo":"RocketChat/Rocket.Chat","slug":"error-invalid-user-0d7726","errorCode":"error-invalid-user","errorMessage":"Invalid user","messagePattern":"Invalid user","errorType":"exception","errorClass":"Meteor.Error","httpStatus":401,"severity":"critical","filePath":"apps/meteor/server/api/v1/im.ts","lineNumber":56,"sourceCode":"import 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}\n\n\tconst subscription = await Subscriptions.findOne({ 'rid': room._id, 'u._id': uid });\n\n\treturn {\n\t\troom,","sourceCodeStart":38,"sourceCodeEnd":74,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/f9d3ec372bb580fa8d036f94cf03925a478ef768/apps/meteor/server/api/v1/im.ts#L38-L74","documentation":"Thrown by findDirectMessageRoom in im.ts (lines 54-59). The authenticated uid was passed to Users.findOneById and no user document was returned. This means the authenticated session's user no longer exists in the database: the account was deleted/deactivated, the user record was purged, or the auth token references a uid that is no longer valid. It is annotated with method: 'findDirectMessageRoom' for diagnostics.","triggerScenarios":"Calling any im.* endpoint through the helper after the authenticated user's document has been removed (deletion, GDPR purge, import/migration mismatch) while the session/token is still being used.","commonSituations":"A long-lived bot token whose user was deactivated/deleted but the token was not revoked. A session kept open after account deletion. A test that deletes the acting user mid-flow. Post-migration uid mismatches.","solutions":["Re-authenticate with a valid user; revoke and reissue tokens for any deleted user.","Confirm the user still exists (GET /api/v1/me will also fail; check the admin Users list) and is active.","If the user was deleted intentionally, stop using that token and provision a new service account/bot user.","Ensure deletion flows also revoke sessions and invalidate API tokens to prevent this."],"exampleFix":"// before\nconst client = new SDK(tokenOfDeletedUser);\nawait client.call('GET', '/api/v1/im.info', { roomId }); // -> error-invalid-user\n\n// after\nconst me = await client.call('GET', '/api/v1/me'); // expect 401; obtain a fresh token for an active user\nconst fresh = await login(activeUsername, activePassword);\nawait new SDK(fresh.token).call('GET', '/api/v1/im.info', { roomId });","handlingStrategy":"validation","validationCode":"// Pre-flight: confirm the token's user still exists before relying on im.* calls.\nconst me = await api.get('/api/v1/me').catch((e) => e);\nif (me instanceof Error || !me?._id) {\n  throw new Error('Auth token is invalid or its user no longer exists; re-authenticate');\n}\nawait api.get('/api/v1/im.info', { roomId });","typeGuard":"function isActiveUser(u) {\n  return u != null && typeof u._id === 'string' && u.active !== false;\n}","tryCatchPattern":"try {\n  await api.get('/api/v1/im.info', { roomId });\n} catch (e) {\n  if (isMeteorError(e) && e.reason === 'error-invalid-user') {\n    // token's user was deleted; revoke and re-authenticate\n    await logoutAndReauthenticate();\n    return;\n  }\n  throw e;\n}","preventionTips":["Revoke API tokens and sessions when deleting/deactivating a user.","Re-authenticate bots/service accounts after user re-provisioning.","Use a dedicated service-account bot user for long-lived automation rather than a personal account.","After migrations, verify uid mapping so tokens reference existing users."],"tags":["rest-api","im","direct-message","authentication","deleted-user","session"],"backgroundTag":null,"analyzedSha":"f9d3ec372bb580fa8d036f94cf03925a478ef768","analyzedAt":"2026-08-12T19:07:17.372Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}