RocketChat/Rocket.Chat · error · Error
error-not-allowed
Error message
error-not-allowed
What it means
Thrown by PUT /livechat/department/:_id when the authenticated user lacks the `manage-livechat-departments` permission. IMPORTANT nuance: the route-level guard (departments.ts:117) allows PUT with hasAny(`manage-livechat-departments`, `add-livechat-department-agents`), but the action body re-checks (departments.ts:143-156) and requires `manage-livechat-departments` specifically. So a user holding only `add-livechat-department-agents` passes the route guard yet fails inside the handler. Returns HTTP 400 { success:false, error:'error-not-allowed' }.
Source
Thrown at apps/meteor/server/api/v1/omnichannel/departments.ts:156
// to show the "new" view. Returning 404 breaks it
return API.v1.success({ department, agents });
},
async put() {
const permissionToSave = await hasPermissionAsync(this.user, 'manage-livechat-departments');
const permissionToAddAgents = await hasPermissionAsync(this.user, 'add-livechat-department-agents');
check(this.bodyParams, {
department: Object,
agents: Match.Maybe(Array),
departmentUnit: Match.Maybe({ _id: Match.Optional(String) }),
});
const { _id } = this.urlParams;
const { department, agents, departmentUnit } = this.bodyParams;
if (!permissionToSave) {
throw new Error('error-not-allowed');
}
const agentParam = permissionToAddAgents && agents ? { upsert: agents } : {};
await saveDepartment(this.userId, _id, department, agentParam, departmentUnit || {});
return API.v1.success({
department: await LivechatDepartment.findOneById(_id),
agents: await LivechatDepartmentAgents.findByDepartmentId(_id).toArray(),
});
},
async delete() {
check(this.urlParams, {
_id: String,
});
const isRemoveEnabled = settings.get<boolean>('Omnichannel_enable_department_removal');
if (!isRemoveEnabled) {View on GitHub (pinned to f9d3ec372b)
Solutions
- Grant the calling user/role the `manage-livechat-departments` permission.
- If the caller only needs to manage agents on a department, use POST /livechat/department/:_id/agents instead of PUT on the department itself.
- Reconcile the route-level vs action-level permission mismatch (the action over-constrains relative to the declared route guard) if the divergence is a bug.
Example fix
// before: role has only 'add-livechat-department-agents' -> PUT /livechat/department/:_id throws error-not-allowed
// after: assign the required permission to the role
await Roles.addPermissionRoles('manage-livechat-departments', ['livechat-manager']); Defensive patterns
Strategy: validation
Validate before calling
const canManage = await hasPermissionAsync(user, 'manage-livechat-departments');
if (!canManage) {
// route to POST /livechat/department/:_id/agents instead, or surface forbidden
throw new Error('caller lacks manage-livechat-departments');
} Type guard
const canManageDepartment = async (user: IUser) => await hasPermissionAsync(user, 'manage-livechat-departments');
Try / catch
try {
await putDepartment(_id, department, agents, departmentUnit);
} catch (e) {
if (e instanceof Error && e.message === 'error-not-allowed') {
// caller needs manage-livechat-departments; fall back to the agents endpoint
} else { throw e; }
} Prevention
- UI should only show the department-edit form to users with `manage-livechat-departments`.
- For agent-only roles, route to /livechat/department/:_id/agents.
- Track the route/action permission divergence (departments.ts:117 vs :143) as a known issue.
When it happens
Trigger: PUT /livechat/department/:_id by a user/role that has `add-livechat-department-agents` but NOT `manage-livechat-departments`. The route guard admits the request, the action then rejects it.
Common situations: An agent-manager role intended only to add agents to a department tries to edit department settings; permission was recently revoked; role misconfiguration; the route/action permission divergence is unintended.
Related errors
- error-not-authorized
- error-forwarding-department-target-not-allowed
- visitor-not-found
- invalid-room
- error-not-allowed
AI-assisted analysis of RocketChat/Rocket.Chat@f9d3ec372b (2026-08-12).
Data as JSON: /api/errors/3481c3c3a86c82c5.
Report an issue: GitHub.