RocketChat/Rocket.Chat · error · Meteor.Error
error-not-allowed
error-not-allowed
Error message
Threads Disabled
What it means
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'.
Source
Thrown at apps/meteor/server/api/v1/chat.ts:282
response: {
400: validateBadRequestErrorResponse,
401: validateUnauthorizedErrorResponse,
200: ajv.compile<void>({
type: 'object',
properties: {
success: {
type: 'boolean',
enum: [true],
},
},
required: ['success'],
additionalProperties: false,
}),
},
},
async function action() {
if (!settings.get<boolean>('Threads_enabled')) {
throw new Meteor.Error('error-not-allowed', 'Threads Disabled');
}
const { tmid } = this.bodyParams;
const thread = await Messages.findOneById(tmid, { projection: { rid: 1 } });
if (!thread?.rid) {
throw new Meteor.Error('error-invalid-message', 'Invalid Message');
}
const [user, room] = await Promise.all([
Users.findOneById(this.userId),
Rooms.findOneById(thread.rid, { projection: { ...roomAccessAttributes, t: 1, _id: 1 } }),
]);
if (!room) {
throw new Meteor.Error('error-room-does-not-exist', 'This room does not exist');
}
View on GitHub (pinned to f9d3ec372b)
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).
Example fix
// before
await fetch('/api/v1/chat.readThread', { method: 'POST', body: JSON.stringify({ tmid }) });
// after - check the setting (exposed via settings/public) first
if (!publicSettings.Threads_enabled) {
hideThreadUI();
return;
}
await fetch('/api/v1/chat.readThread', { method: 'POST', body: JSON.stringify({ tmid }) }); Defensive patterns
Strategy: validation
Validate before calling
// Gate thread UI on the feature setting
async function threadsEnabled() {
const res = await fetch('/api/v1/settings/public');
const { settings } = await res.json();
return Boolean(settings.Threads_enabled);
} Type guard
function isThreadsEnabled(settings) {
return Boolean(settings && settings.Threads_enabled === true);
} Try / catch
try {
await api.readThread({ tmid });
} catch (e) {
if (e.error === 'error-not-allowed' && /Threads Disabled/.test(e.reason)) {
hideThreadUI();
return;
}
throw e;
} Prevention
- 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.
When it happens
Trigger: Calling chat.readThread on a workspace where the Threads feature has been turned off in Administration > Settings.
Common situations: Admin disabled threads; fresh install with threads off by default; feature flag flipped during a deploy.
Related errors
- LDAP_disabled
- error-invalid-message
- error-room-does-not-exist
- error-updatedSince-param-invalid
- LDAP_disabled
AI-assisted analysis of RocketChat/Rocket.Chat@f9d3ec372b (2026-08-12).
Data as JSON: /api/errors/6633d66ebba9f1b8.
Report an issue: GitHub.