{"record":{"id":"f9ecc90f0494fd5e","repo":"RocketChat/Rocket.Chat","slug":"error-contact-manager-not-found-f9ecc9","errorCode":"error-contact-manager-not-found","errorMessage":"error-contact-manager-not-found","messagePattern":"error-contact-manager-not-found","errorType":"error_code","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"apps/meteor/server/lib/omnichannel/contacts/validateContactManager.ts","lineNumber":7,"sourceCode":"import type { IUser } from '@rocket.chat/core-typings';\nimport { Users } from '@rocket.chat/models';\n\nexport async function validateContactManager(contactManagerUserId: string) {\n\tconst contactManagerUser = await Users.findOneAgentById<Pick<IUser, '_id'>>(contactManagerUserId, { projection: { _id: 1 } });\n\tif (!contactManagerUser) {\n\t\tthrow new Error('error-contact-manager-not-found');\n\t}\n}\n","sourceCodeStart":1,"sourceCodeEnd":10,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/server/lib/omnichannel/contacts/validateContactManager.ts#L1-L10","documentation":"validateContactManager is the id-based manager check used by updateContact and resolveContactConflicts. Users.findOneAgentById looks a user up by _id AND requires them to be an agent; null means the passed contactManagerUserId either does not exist or lacks the livechat-agent role. Note the contrast with registerContact, which validates by username — here the caller must supply the manager's user _id.","triggerScenarios":"POST/PUT contact endpoints with contactManager set to a user id that is unknown, deleted, or not a livechat agent; very commonly, passing the manager's username or email where the _id is required.","commonSituations":"Client sends username instead of _id because the register endpoint uses username; agent removed from the agent list but still referenced by old records; user record purged by a retention job.","solutions":["Confirm you are sending the manager's user _id (not username/email) — resolve it first via users.info if needed","Verify the id maps to an agent: GET /api/v1/livechat/agents or users.info showing the 'livechat-agent' role","Add the livechat-agent role to the intended manager, or omit contactManager / send it empty to unset a manager"],"exampleFix":"// before\nawait updateContact({ contactId, contactManager: 'johndoe' }); // username, not _id\n\n// after\nconst { user } = await GET('/api/v1/users.info?username=johndoe');\nawait updateContact({ contactId, contactManager: user._id });","handlingStrategy":"validation","validationCode":"const agent = await Users.findOneAgentById(contactManagerUserId, { projection: { _id: 1 } });\nif (!agent) throw new Error('contactManager must be an existing livechat agent user _id');\nawait updateContact({ ...params, contactManager: contactManagerUserId });","typeGuard":"const isAgentUserId = (v: unknown): v is string =>\n  typeof v === 'string' && /^[0-9a-f]{17}$/i.test(v); // user _id shape, NOT a username","tryCatchPattern":"try {\n  await updateContact(params);\n} catch (err) {\n  if (err instanceof Error && err.message === 'error-contact-manager-not-found') {\n    // id unknown or user lacks livechat-agent role: resolve real agent _id via livechat/agents and retry\n  }\n  throw err;\n}","preventionTips":["Pick managers from GET /api/v1/livechat/agents and store their _id","Remember the id-based field here vs the username-based field in registerContact","To unset a manager, pass contactManager as empty ('' in params) rather than a bogus id"],"tags":["omnichannel","livechat","contacts","contact-manager","roles","user-lookup","validation"],"backgroundTag":"user-missing-role","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}