{"record":{"id":"83f7951b5be15c70","repo":"RocketChat/Rocket.Chat","slug":"isagentavailabletotakecontactinquiryresult-error","errorCode":null,"errorMessage":"isAgentAvailableToTakeContactInquiryResult.error","messagePattern":"isAgentAvailableToTakeContactInquiryResult\\.error","errorType":"exception","errorClass":"Meteor.Error","httpStatus":null,"severity":"warning","filePath":"apps/meteor/server/lib/omnichannel/takeInquiry.ts","lineNumber":55,"sourceCode":"\t\t\tmethod: 'livechat:takeInquiry',\n\t\t\t...(process.env.TEST_MODE && {\n\t\t\t\tLivechat_enabled_when_agent_idle: settings.get<boolean>('Livechat_enabled_when_agent_idle'),\n\t\t\t\tLivechat_accept_chats_with_no_agents: settings.get<boolean>('Livechat_accept_chats_with_no_agents'),\n\t\t\t\tuser: await Users.findOneById(userId),\n\t\t\t}),\n\t\t});\n\t}\n\n\tconst room = await LivechatRooms.findOneById(inquiry.rid);\n\tif (!room || !(await Omnichannel.isWithinMACLimit(room))) {\n\t\tthrow new Meteor.Error('error-mac-limit-reached');\n\t}\n\n\tconst contactId = room.contactId ?? (await migrateVisitorIfMissingContact(room.v._id, room.source));\n\tif (contactId) {\n\t\tconst isAgentAvailableToTakeContactInquiryResult = await isAgentAvailableToTakeContactInquiry(inquiry.v._id, room.source, contactId);\n\t\tif (!isAgentAvailableToTakeContactInquiryResult.value) {\n\t\t\tthrow new Meteor.Error(isAgentAvailableToTakeContactInquiryResult.error);\n\t\t}\n\t}\n\n\tconst agent = {\n\t\tagentId: user._id,\n\t\tusername: user.username,\n\t};\n\n\tawait RoutingManager.takeInquiry(inquiry, agent, options ?? {}, room);\n};\n","sourceCodeStart":37,"sourceCodeEnd":66,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/server/lib/omnichannel/takeInquiry.ts#L37-L66","documentation":"takeInquiry consults isAgentAvailableToTakeContactInquiry; on a false result it rethrows Meteor.Error(result.error) with a code produced by that check. In Community Edition the base implementation always returns { value: true }, so this only fires on Enterprise with the 'contact-id-verification' license module. The EE patch returns one of: 'error-invalid-contact' (contact record missing/disabled), 'error-unknown-contact' (contact flagged unknown while Livechat_Block_Unknown_Contacts is on), or 'error-unverified-contact' (channel unverified while Livechat_Block_Unverified_Contacts is on).","triggerScenarios":"An EE workspace with the contact-id-verification module takes an inquiry where: the contact document was deleted/disabled, an unknown contact is blocked by Livechat_Block_Unknown_Contacts, or the visitor's channel isn't verified and Livechat_Block_Unverified_Contacts is enabled.","commonSituations":"Compliance deployments that block unknown/unverified contacts (WhatsApp/SMS verification flows), contacts merged or deleted in the contact manager while their inquiry was queued, or the verification settings enabled after inquiries were already created.","solutions":["Read err.error from the caught Meteor.Error to know which of the three codes fired","For error-invalid-contact: restore/enable the contact record in the Contacts manager or let the inquiry be closed","For error-unknown-contact: mark the contact as known or disable Livechat_Block_Unknown_Contacts","For error-unverified-contact: verify the contact's channel in the contact record or disable Livechat_Block_Unverified_Contacts","Confirm the license actually includes contact-id-verification; without the module the patched check is inactive"],"exampleFix":"// before\nawait Meteor.callAsync('livechat:takeInquiry', inquiryId);\n\n// after\ntry {\n  await Meteor.callAsync('livechat:takeInquiry', inquiryId);\n} catch (err) {\n  if (['error-invalid-contact', 'error-unknown-contact', 'error-unverified-contact'].includes(err?.error)) {\n    // surface contact verification guidance to the agent instead of a generic failure\n    return notifyContactBlocked(err.error);\n  }\n  throw err;\n}","handlingStrategy":"try-catch","validationCode":"// if you control the caller and license, pre-check the same conditions the EE patch enforces\nconst contact = await LivechatContacts.findOneEnabledById(contactId, { projection: { unknown: 1, channels: 1 } });\nconst blocked = !contact\n  || (contact.unknown && settings.get('Livechat_Block_Unknown_Contacts'))\n  || (!hasVerifiedChannel(contact.channels, visitorId, source) && settings.get('Livechat_Block_Unverified_Contacts'));\nif (blocked) {\n  return warnAgent('contact is blocked by verification policy');\n}\nawait Meteor.callAsync('livechat:takeInquiry', inquiryId);","typeGuard":"type Availability = { error: string; value: false } | { value: true };\n\nfunction isBlockedResult(v: Availability): v is { error: string; value: false } {\n  return v.value === false;\n}","tryCatchPattern":"try {\n  await Meteor.callAsync('livechat:takeInquiry', inquiryId);\n} catch (err) {\n  const blocked = ['error-invalid-contact', 'error-unknown-contact', 'error-unverified-contact'];\n  if (err instanceof Meteor.Error && blocked.includes(err.error)) {\n    // guide the agent: verify the contact or adjust block-unknown/unverified settings\n  } else {\n    throw err;\n  }\n}","preventionTips":["Know your license modules — without contact-id-verification this branch never fires","Keep contact records enabled and channels verified when block settings are on","Train agents that these codes mean policy-blocked contacts, not system failures"],"tags":["omnichannel","contact-verification","enterprise","take-inquiry","contacts"],"backgroundTag":"contact-verification-blocked","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","contentChangedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}