{"record":{"id":"50fdba0a7a2ecea7","repo":"RocketChat/Rocket.Chat","slug":"error-not-allowed-to-close-conversation","errorCode":null,"errorMessage":"error-not-allowed-to-close-conversation","messagePattern":"error-not-allowed-to-close-conversation","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"apps/meteor/server/api/v1/omnichannel/room.ts","lineNumber":138,"sourceCode":"\t\t\t\tthrow new Error('invalid-room');\n\t\t\t}\n\n\t\t\treturn API.v1.success({ room: froom, newRoom: false });\n\t\t},\n\t},\n);\n\n// Note: use this route if a visitor is closing a room\n// If a RC user(like eg agent) is closing a room, use the `livechat/room.closeByUser` route\nAPI.v1.addRoute(\n\t'livechat/room.close',\n\t{ validateParams: isPOSTLivechatRoomCloseParams },\n\t{\n\t\tasync post() {\n\t\t\tconst { rid, token } = this.bodyParams;\n\n\t\t\tif (!rcSettings.get('Omnichannel_allow_visitors_to_close_conversation')) {\n\t\t\t\tthrow new Error('error-not-allowed-to-close-conversation');\n\t\t\t}\n\n\t\t\tconst visitor = await findGuest(token);\n\t\t\tif (!visitor) {\n\t\t\t\tthrow new Error('invalid-token');\n\t\t\t}\n\n\t\t\tconst room = await findRoom(token, rid);\n\t\t\tif (!room) {\n\t\t\t\tthrow new Error('invalid-room');\n\t\t\t}\n\n\t\t\tif (!room.open) {\n\t\t\t\tthrow new Error('room-closed');\n\t\t\t}\n\n\t\t\tconst language = rcSettings.get<string>('Language') || 'en';\n\t\t\tconst comment = i18n.t('Closed_by_visitor', { lng: language });","sourceCodeStart":120,"sourceCodeEnd":156,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/f9d3ec372bb580fa8d036f94cf03925a478ef768/apps/meteor/server/api/v1/omnichannel/room.ts#L120-L156","documentation":"Thrown in the POST handler of 'livechat/room.close' (room.ts:137-139) when the setting 'Omnichannel_allow_visitors_to_close_conversation' is disabled (falsy). This is the very first check in the handler — it fires before any token or room validation. The setting is read via rcSettings.get() from the server settings store.","triggerScenarios":"Calling POST /api/v1/livechat/room.close when the admin setting 'Omnichannel_allow_visitors_to_close_conversation' is set to false. Any request body (even valid ones) will trigger this error before token/room checks.","commonSituations":"Administrator disabled visitor-initiated room closing in Omnichannel settings; fresh installation where the setting defaults to false; setting was changed during deployment without updating the client widget to hide the close button.","solutions":["Enable the setting in Admin > Omnichannel > Allow visitors to close conversation (set to true).","Via settings API or CLI: set Omnichannel_allow_visitors_to_close_conversation to true.","If the setting should remain disabled, use the authenticated 'livechat/room.closeByUser' endpoint instead (requires an agent/admin user with 'close-livechat-room' permission)."],"exampleFix":"// before — setting is disabled, visitors cannot close\nPOST /api/v1/livechat/room.close\n// throws 'error-not-allowed-to-close-conversation'\n\n// after — enable in admin settings, then retry\n// Admin > Omnichannel > Allow visitors to close conversation = true\nPOST /api/v1/livechat/room.close\n// { rid: '...', token: '...' }","handlingStrategy":"validation","validationCode":"// Check the setting before attempting to close a room as a visitor\nconst allowClose = await getSetting('Omnichannel_allow_visitors_to_close_conversation');\nif (!allowClose) {\n  // use the authenticated room.closeByUser endpoint instead, or enable the setting\n  throw new Error('Visitor close is disabled — use room.closeByUser as an agent');\n}","typeGuard":null,"tryCatchPattern":"try {\n  await api.post('/livechat/room.close', { rid, token });\n} catch (err) {\n  if (err.message === 'error-not-allowed-to-close-conversation') {\n    // fall back to authenticated close-by-user endpoint\n    await api.post('/livechat/room.closeByUser', { rid, comment: 'Closed by agent' }, { auth: true });\n  }\n}","preventionTips":["Check the Omnichannel_allow_visitors_to_close_conversation setting before enabling the close button in the widget.","If the setting must stay disabled, use the authenticated 'livechat/room.closeByUser' endpoint instead.","Sync the widget UI state with the server setting to hide/disable the close button when not allowed."],"tags":["omnichannel","settings","configuration","permissions","room"],"backgroundTag":null,"analyzedSha":"f9d3ec372bb580fa8d036f94cf03925a478ef768","analyzedAt":"2026-08-12T19:07:17.372Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}