{"record":{"id":"6633d66ebba9f1b8","repo":"RocketChat/Rocket.Chat","slug":"error-not-allowed-6633d6","errorCode":"error-not-allowed","errorMessage":"Threads Disabled","messagePattern":"Threads Disabled","errorType":"exception","errorClass":"Meteor.Error","httpStatus":null,"severity":"error","filePath":"apps/meteor/server/api/v1/chat.ts","lineNumber":282,"sourceCode":"\t\t\tresponse: {\n\t\t\t\t400: validateBadRequestErrorResponse,\n\t\t\t\t401: validateUnauthorizedErrorResponse,\n\t\t\t\t200: ajv.compile<void>({\n\t\t\t\t\ttype: 'object',\n\t\t\t\t\tproperties: {\n\t\t\t\t\t\tsuccess: {\n\t\t\t\t\t\t\ttype: 'boolean',\n\t\t\t\t\t\t\tenum: [true],\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\trequired: ['success'],\n\t\t\t\t\tadditionalProperties: false,\n\t\t\t\t}),\n\t\t\t},\n\t\t},\n\t\tasync function action() {\n\t\t\tif (!settings.get<boolean>('Threads_enabled')) {\n\t\t\t\tthrow new Meteor.Error('error-not-allowed', 'Threads Disabled');\n\t\t\t}\n\n\t\t\tconst { tmid } = this.bodyParams;\n\n\t\t\tconst thread = await Messages.findOneById(tmid, { projection: { rid: 1 } });\n\t\t\tif (!thread?.rid) {\n\t\t\t\tthrow new Meteor.Error('error-invalid-message', 'Invalid Message');\n\t\t\t}\n\n\t\t\tconst [user, room] = await Promise.all([\n\t\t\t\tUsers.findOneById(this.userId),\n\t\t\t\tRooms.findOneById(thread.rid, { projection: { ...roomAccessAttributes, t: 1, _id: 1 } }),\n\t\t\t]);\n\n\t\t\tif (!room) {\n\t\t\t\tthrow new Meteor.Error('error-room-does-not-exist', 'This room does not exist');\n\t\t\t}\n","sourceCodeStart":264,"sourceCodeEnd":300,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/f9d3ec372bb580fa8d036f94cf03925a478ef768/apps/meteor/server/api/v1/chat.ts#L264-L300","documentation":"Thrown by the chat.readThread endpoint when the workspace setting Threads_enabled is false. The check fires before any input validation, so even a perfectly-formed request is rejected while threads are disabled. Meteor.Error code 'error-not-allowed'.","triggerScenarios":"Calling chat.readThread on a workspace where the Threads feature has been turned off in Administration > Settings.","commonSituations":"Admin disabled threads; fresh install with threads off by default; feature flag flipped during a deploy.","solutions":["Enable Threads_enabled in Administration > Settings > Threads.","Gate the client thread UI on a feature flag / settings query so readThread is never called when threads are off.","Handle error-not-allowed with message 'Threads Disabled' gracefully (hide thread controls)."],"exampleFix":"// before\nawait fetch('/api/v1/chat.readThread', { method: 'POST', body: JSON.stringify({ tmid }) });\n\n// after - check the setting (exposed via settings/public) first\nif (!publicSettings.Threads_enabled) {\n  hideThreadUI();\n  return;\n}\nawait fetch('/api/v1/chat.readThread', { method: 'POST', body: JSON.stringify({ tmid }) });","handlingStrategy":"validation","validationCode":"// Gate thread UI on the feature setting\nasync function threadsEnabled() {\n  const res = await fetch('/api/v1/settings/public');\n  const { settings } = await res.json();\n  return Boolean(settings.Threads_enabled);\n}","typeGuard":"function isThreadsEnabled(settings) {\n  return Boolean(settings && settings.Threads_enabled === true);\n}","tryCatchPattern":"try {\n  await api.readThread({ tmid });\n} catch (e) {\n  if (e.error === 'error-not-allowed' && /Threads Disabled/.test(e.reason)) {\n    hideThreadUI();\n    return;\n  }\n  throw e;\n}","preventionTips":["Read Threads_enabled from public settings before rendering thread controls.","Have admins enable Threads if the feature is required.","Surface a clear 'threads disabled' message instead of an error."],"tags":["chat","threads","configuration","feature-flag","settings"],"backgroundTag":null,"analyzedSha":"f9d3ec372bb580fa8d036f94cf03925a478ef768","analyzedAt":"2026-08-12T19:07:17.372Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}