{"record":{"id":"85fa242e0b60b17d","repo":"RocketChat/Rocket.Chat","slug":"invalid-user-85fa24","errorCode":null,"errorMessage":"invalid-user","messagePattern":"invalid-user","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"apps/meteor/ee/server/api/v1/omnichannel/lib/monitors.ts","lineNumber":67,"sourceCode":"}\n\nexport async function findMonitorByUsername({ username }: { username: string }): Promise<IUser> {\n\tconst user = await Users.findOne(\n\t\t{ username, roles: 'livechat-monitor' },\n\t\t{\n\t\t\tprojection: {\n\t\t\t\tusername: 1,\n\t\t\t\tname: 1,\n\t\t\t\tstatus: 1,\n\t\t\t\tstatusLivechat: 1,\n\t\t\t\temails: 1,\n\t\t\t\tlivechat: 1,\n\t\t\t},\n\t\t},\n\t);\n\n\tif (!user) {\n\t\tthrow new Error('invalid-user');\n\t}\n\n\treturn user;\n}\n","sourceCodeStart":49,"sourceCodeEnd":72,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/f9d3ec372bb580fa8d036f94cf03925a478ef768/apps/meteor/ee/server/api/v1/omnichannel/lib/monitors.ts#L49-L72","documentation":"Thrown by findMonitorByUsername when no user matches the username AND the 'livechat-monitor' role. The lookup requires both conditions: a user with that exact username who also holds the livechat-monitor role. Plain Error, code 'invalid-user' (note: no 'error-' prefix, unlike most codes in this area).","triggerScenarios":"Calling findMonitorByUsername with a username that does not exist, or exists but is not a livechat-monitor; username case mismatch (Mongo exact match); monitor was deactivated/role removed.","commonSituations":"Monitor demoted/removed from the livechat-monitor role but still referenced; case-sensitivity in username lookup; typo in the username; monitor deleted.","solutions":["Confirm the user exists and holds the 'livechat-monitor' role via Users.findOne before calling.","Match the username casing exactly (consider lowercasing both sides if usernames are case-insensitive elsewhere).","Re-grant the livechat-monitor role if it was removed inadvertently.","Handle the not-found case in the caller rather than propagating the raw error."],"exampleFix":"// before: assume monitor exists\nconst monitor = await findMonitorByUsername({ username });\n\n// after: validate role membership first\nconst candidate = await Users.findOne({ username }, { projection: { roles: 1, username: 1 } });\nif (!candidate || !candidate.roles?.includes('livechat-monitor')) {\n  throw new NotFoundError('livechat-monitor');\n}\nconst monitor = await findMonitorByUsername({ username });","handlingStrategy":"validation","validationCode":"// Validate the monitor exists with the role before lookup\nimport { Users } from '@rocket.chat/models';\nconst candidate = await Users.findOne({ username }, { projection: { roles: 1, username: 1 } });\nif (!candidate || !candidate.roles?.includes('livechat-monitor')) {\n  throw new NotFoundError('livechat-monitor');\n}\nawait findMonitorByUsername({ username });","typeGuard":"function isLivechatMonitor(u: { roles?: string[] } | null | undefined): u is { roles: string[] } {\n  return Array.isArray(u?.roles) && u.roles.includes('livechat-monitor');\n}","tryCatchPattern":"try {\n  return await findMonitorByUsername({ username });\n} catch (e) {\n  if (e.message === 'invalid-user') {\n    return null; // caller treats null as not-found\n  }\n  throw e;\n}","preventionTips":["Match username casing exactly; normalize case if usernames are case-insensitive in your UI.","Remove dangling monitor references when a user loses the livechat-monitor role."],"tags":["omnichannel","livechat","monitors","not-found"],"backgroundTag":null,"analyzedSha":"f9d3ec372bb580fa8d036f94cf03925a478ef768","analyzedAt":"2026-08-12T19:07:17.372Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}