{"record":{"id":"f92f99c07f3d15c8","repo":"RocketChat/Rocket.Chat","slug":"error-contact-not-found","errorCode":null,"errorMessage":"error-contact-not-found","messagePattern":"error-contact-not-found","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"apps/meteor/ee/server/api/v1/omnichannel/lib/contacts.ts","lineNumber":12,"sourceCode":"import type { IUser, ILivechatContactVisitorAssociation } from '@rocket.chat/core-typings';\nimport { License } from '@rocket.chat/license';\nimport { LivechatContacts, LivechatRooms, LivechatVisitors } from '@rocket.chat/models';\n\nimport { i18n } from '../../../../../../server/lib/i18n';\nimport { closeRoom } from '../../../../../../server/lib/omnichannel/closeRoom';\n\nexport async function changeContactBlockStatus({ block, visitor }: { visitor: ILivechatContactVisitorAssociation; block: boolean }) {\n\tconst result = await LivechatContacts.setChannelBlockStatus(visitor, block);\n\n\tif (!result.modifiedCount) {\n\t\tthrow new Error('error-contact-not-found');\n\t}\n}\n\nexport function ensureSingleContactLicense() {\n\tif (!License.hasModule('contact-id-verification')) {\n\t\tthrow new Error('error-action-not-allowed');\n\t}\n}\n\nexport async function closeBlockedRoom(association: ILivechatContactVisitorAssociation, user: IUser) {\n\tconst visitor = await LivechatVisitors.findOneById(association.visitorId);\n\n\tif (!visitor) {\n\t\tthrow new Error('error-visitor-not-found');\n\t}\n\n\tconst room = await LivechatRooms.findOneOpenByContactChannelVisitor(association);\n","sourceCodeStart":1,"sourceCodeEnd":30,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/f9d3ec372bb580fa8d036f94cf03925a478ef768/apps/meteor/ee/server/api/v1/omnichannel/lib/contacts.ts#L1-L30","documentation":"Thrown by changeContactBlockStatus when LivechatContacts.setChannelBlockStatus reports zero modified documents. This means no contact matched the supplied visitor association (channel + visitorId), so the block/unblock operation had no effect. Plain Error, code 'error-contact-not-found'.","triggerScenarios":"Calling changeContactBlockStatus with a visitor association whose visitorId or channel does not match any LivechatContacts document; contact was deleted between lookup and update; wrong tenant/workspace context.","commonSituations":"Stale visitorId cached on the client after a contact merge; channel identifier typo; contact deleted by another process; multi-instance setup querying the wrong DB.","solutions":["Verify the contact exists: query LivechatContacts by the same visitor association before calling.","Refresh the visitorId/channel from the upstream source and retry.","Check that the correct workspace/DB is targeted (sharded/multi-instance).","Handle the no-op case gracefully if the contact may already be removed."],"exampleFix":"// before: blind update\nawait changeContactBlockStatus({ visitor: assoc, block: true });\n\n// after: verify existence first\nconst existing = await LivechatContacts.findOneByVisitorAssociation(assoc);\nif (!existing) throw new NotFoundError('contact');\nawait changeContactBlockStatus({ visitor: assoc, block: true });","handlingStrategy":"validation","validationCode":"// Verify the contact exists before toggling block status\nimport { LivechatContacts } from '@rocket.chat/models';\nconst existing = await LivechatContacts.findOneByVisitorAssociation(visitor);\nif (!existing) {\n  throw new NotFoundError('contact');\n}\nawait changeContactBlockStatus({ visitor, block });","typeGuard":null,"tryCatchPattern":"try {\n  await changeContactBlockStatus({ visitor, block });\n} catch (e) {\n  if (e.message === 'error-contact-not-found') {\n    // refresh contact data and retry once, or skip\n    return { ok: false, reason: 'contact-missing' };\n  }\n  throw e;\n}","preventionTips":["Do not cache visitor associations across long-lived sessions; refetch before mutating.","Treat a zero-modifiedCount result as a soft no-op when the contact may already be removed."],"tags":["omnichannel","contacts","livechat","not-found"],"backgroundTag":null,"analyzedSha":"f9d3ec372bb580fa8d036f94cf03925a478ef768","analyzedAt":"2026-08-12T19:07:17.372Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}