{"record":{"id":"e0321e77779ab83d","repo":"RocketChat/Rocket.Chat","slug":"error-action-not-allowed-e0321e","errorCode":null,"errorMessage":"error-action-not-allowed","messagePattern":"error-action-not-allowed","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"apps/meteor/ee/server/api/v1/omnichannel/lib/contacts.ts","lineNumber":18,"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\n\tif (!room) {\n\t\treturn;\n\t}\n\n\treturn closeRoom({ room, visitor, comment: i18n.t('close-blocked-room-comment'), user });\n}","sourceCodeStart":1,"sourceCodeEnd":36,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/f9d3ec372bb580fa8d036f94cf03925a478ef768/apps/meteor/ee/server/api/v1/omnichannel/lib/contacts.ts#L1-L36","documentation":"Thrown by ensureSingleContactLicense when the license lacks the 'contact-id-verification' module. Single-contact verification (binding a visitor to one verified contact) is an Enterprise feature; callers must check the license before using contact-verification APIs. Plain Error, code 'error-action-not-allowed'.","triggerScenarios":"Invoking any omnichannel code path that calls ensureSingleContactLicense (contact verification, block/unblock flows tied to verified contacts) on a server without the contact-id-verification license module.","commonSituations":"CE deployment; Enterprise license without the contact-id-verification add-on; trial expired; feature gated off by license tier.","solutions":["Apply an Enterprise license that includes contact-id-verification.","Call ensureSingleContactLicense() up front and degrade gracefully when it throws, instead of letting it surface mid-flow.","Disable the UI entry points that trigger contact verification when the module is absent.","Verify the active module list via the workspace/license API."],"exampleFix":"// before: feature used unconditionally\nawait verifyContact(visitor);\n\n// after: probe capability first\ntry {\n  ensureSingleContactLicense();\n  await verifyContact(visitor);\n} catch (e) {\n  // feature not licensed; disable flow\n}","handlingStrategy":"try-catch","validationCode":"// Probe license capability up front\nimport { License } from '@rocket.chat/license';\nfunction contactVerificationAvailable(): boolean {\n  return License.hasModule('contact-id-verification');\n}\nif (!contactVerificationAvailable()) {\n  // disable flow gracefully\n  return;\n}","typeGuard":null,"tryCatchPattern":"try {\n  ensureSingleContactLicense();\n  await runContactVerificationFlow();\n} catch (e) {\n  if (e.message === 'error-action-not-allowed') {\n    disableContactVerificationUi();\n    return;\n  }\n  throw e;\n}","preventionTips":["Centralize license probes for contact verification in one guard the UI consults before showing the feature.","Disable related omnichannel automations when the module is not licensed."],"tags":["enterprise","license","omnichannel","contacts"],"backgroundTag":null,"analyzedSha":"f9d3ec372bb580fa8d036f94cf03925a478ef768","analyzedAt":"2026-08-12T19:07:17.372Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}