{"record":{"id":"985695e06f666ba4","repo":"RocketChat/Rocket.Chat","slug":"error-visitor-not-found","errorCode":"error-visitor-not-found","errorMessage":"error-visitor-not-found","messagePattern":"error-visitor-not-found","errorType":"exception","errorClass":"Error","httpStatus":400,"severity":"error","filePath":"apps/meteor/ee/server/api/v1/omnichannel/lib/contacts.ts","lineNumber":26,"sourceCode":"export 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\n\tif (!room) {\n\t\treturn;\n\t}\n\n\treturn closeRoom({ room, visitor, comment: i18n.t('close-blocked-room-comment'), user });\n}\n","sourceCodeStart":8,"sourceCodeEnd":37,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/ee/server/api/v1/omnichannel/lib/contacts.ts#L8-L37","documentation":"closeBlockedRoom resolves the visitor via LivechatVisitors.findOneById(association.visitorId) before closing the associated room; if the visitor document is gone it throws 'error-visitor-not-found'. Contact records can outlive their visitor documents (deletion, imports), producing this during block flows.","triggerScenarios":"Blocking a contact whose contact record exists but whose visitor document was deleted; a visitorId copied from another workspace or import.","commonSituations":"Visitors purged by retention/cleanup jobs while contacts remain; data imports that created contacts without matching visitor docs.","solutions":["Verify the visitor exists (visitors API / LivechatVisitors.findOneById) before blocking","Repair the data: re-create the visitor or remove the orphaned contact","If the flow allows, skip room-closing when the visitor is gone"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"import { LivechatVisitors } from '@rocket.chat/models';\n\nconst visitor = await LivechatVisitors.findOneById(association.visitorId);\nif (!visitor) {\n  throw new Error('visitor document missing - repair or skip room closing');\n}\nawait closeBlockedRoom(association, user);","typeGuard":null,"tryCatchPattern":"try {\n  await closeBlockedRoom(association, user);\n} catch (error) {\n  if (error instanceof Error && error.message === 'error-visitor-not-found') {\n    // orphaned contact: log data inconsistency instead of failing the whole block flow\n    logger.warn('contact without visitor', association);\n    return;\n  }\n  throw error;\n}","preventionTips":["Purge or repair contacts whose visitor documents were deleted","Validate visitor existence before block operations that cascade into room closing","Watch retention/cleanup jobs that delete visitors but not contacts"],"tags":["omnichannel","contacts","livechat","not-found"],"backgroundTag":"resource-not-found","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","contentChangedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}