RocketChat/Rocket.Chat · error · Meteor.Error
error-endpoint-disabled
error-endpoint-disabled
Error message
This endpoint is disabled
What it means
Thrown by GET /api/v1/im.messages.others, an admin endpoint that reads other users' direct-message history. The guard at apps/meteor/server/api/v1/im.ts:791 rejects every call unless the workspace setting API_Enable_Direct_Message_History_EndPoint is strictly true; the setting defaults to false (apps/meteor/server/settings/general.ts:9). The check runs before any parameter validation, so even perfectly-formed requests fail while it is off.
Solutions
- Enable the setting: Administration -> General -> REST API -> Enable Direct Message History EndPoint, or POST {"value": true} to /api/v1/settings/API_Enable_Direct_Message_History_EndPoint with an admin token
- Confirm the caller has view-room-administration, otherwise the next response is 403
- If the setting cannot be changed, remove the call - the data is intentionally unavailable on that server
Example fix
# before
curl -H "X-Auth-Token: $TOKEN" -H "X-User-Id: $UID" \
"https://chat.example.com/api/v1/im.messages.others?roomId=AbCdEf123"
# => 400 error-endpoint-disabled
# after: enable it first (admin token), then call
curl -X POST -H "X-Auth-Token: $ADMIN_TOKEN" -H "X-User-Id: $ADMIN_UID" \
-H "Content-Type: application/json" -d '{"value": true}' \
"https://chat.example.com/api/v1/settings/API_Enable_Direct_Message_History_EndPoint"
curl -H "X-Auth-Token: $TOKEN" -H "X-User-Id: $UID" \
"https://chat.example.com/api/v1/im.messages.others?roomId=AbCdEf123" Defensive patterns
Strategy: try-catch
Validate before calling
const res = await fetch(`${server}/api/v1/settings/API_Enable_Direct_Message_History_EndPoint`, {
headers: { 'X-Auth-Token': adminToken, 'X-User-Id': adminUserId },
});
const { value } = await res.json();
if (value !== true) {
throw new Error('im.messages.others is disabled on this server (API_Enable_Direct_Message_History_EndPoint=false)');
} Try / catch
try {
const result = await api.get('/api/v1/im.messages.others', { params: { roomId } });
} catch (err) {
if (err.response?.body?.error === 'error-endpoint-disabled') {
// permanent config state - surface to operator, never retry
throw new ConfigurationError('DM history endpoint disabled by workspace setting');
}
throw err;
} Prevention
- Feature-detect optional endpoints before shipping calls to them; treat error-endpoint-disabled as a permanent condition
- Keep a per-environment config checklist - dev and prod workspaces rarely share optional API flags
- Never auto-retry a 400-class disabled-endpoint response
When it happens
Trigger: Calling GET /api/v1/im.messages.others?roomId=... (with an account holding view-room-administration) on any workspace where API_Enable_Direct_Message_History_EndPoint is false or untouched (default). If the caller lacks the permission you get 403 instead and never reach this throw.
Common situations: Fresh installs; compliance-hardened workspaces where the DM-history endpoint was intentionally disabled; scripts developed against a dev server with the flag on and then pointed at production where it is off.
Related errors
- error-endpoint-disabled
- LDAP_disabled
- error-contact-has-open-rooms
- error-id-param-not-provided
- error-invalid-room
AI-assisted analysis of RocketChat/Rocket.Chat@e4b8178b20 (2026-08-18).
Data as JSON: /api/errors/3df1cf14e5cd509f.
Report an issue: GitHub.
Appendix: source
Thrown at apps/meteor/server/api/v1/im.ts:798
required: ['ims', 'offset', 'count', 'total', 'success'],
additionalProperties: false,
});
const dmMessagesOthersEndpointsProps = {
authRequired: true as const,
permissionsRequired: ['view-room-administration'],
response: {
200: paginatedMessagesResponseSchema,
400: validateBadRequestErrorResponse,
401: validateUnauthorizedErrorResponse,
403: validateForbiddenErrorResponse,
},
};
const dmMessagesOthersAction = <Path extends string>(_name: Path): TypedAction<typeof dmMessagesOthersEndpointsProps, Path> =>
async function action() {
if (settings.get('API_Enable_Direct_Message_History_EndPoint') !== true) {
throw new Meteor.Error('error-endpoint-disabled', 'This endpoint is disabled', {
route: '/api/v1/im.messages.others',
});
}
const { roomId } = this.queryParams;
if (!roomId) {
throw new Meteor.Error('error-roomid-param-not-provided', 'The parameter "roomId" is required');
}
const room = await Rooms.findOneById<Pick<IRoom, '_id' | 't'>>(roomId, { projection: { _id: 1, t: 1 } });
if (!room || room?.t !== 'd') {
throw new Meteor.Error('error-room-not-found', `No direct message room found by the id of: ${roomId}`);
}
const { offset, count } = await getPaginationItems(this.queryParams);
const { sort, fields, query } = await this.parseJsonQuery();
const ourQuery = Object.assign({}, query, { rid: room._id });
View on GitHub (pinned to e4b8178b20)