RocketChat/Rocket.Chat · error · Error
error-failed-to-delete-department
error-failed-to-delete-department
Error message
error-failed-to-delete-department
What it means
Thrown by `removeDepartment` when `LivechatDepartment.removeById(_id)` returns a write result with `acknowledged !== true`. This is a MongoDB driver-level outcome: the deleteOne was not acknowledged by the server (unacknowledged write concern, connection drop mid-write, or driver error surfaced through the result rather than an exception).
Source
Thrown at apps/meteor/server/lib/omnichannel/departmentsLib.ts:225
// Visitor is already validated at this point
return LivechatVisitors.updateDepartmentById(visitorId, department);
}
export async function removeDepartment(departmentId: string) {
livechatLogger.debug({ msg: 'Removing department', departmentId });
const department = await LivechatDepartment.findOneById<Pick<ILivechatDepartment, '_id' | 'businessHourId' | 'parentId'>>(departmentId, {
projection: { _id: 1, businessHourId: 1, parentId: 1 },
});
if (!department) {
throw new Error('error-department-not-found');
}
const { _id } = department;
const ret = await LivechatDepartment.removeById(_id);
if (ret.acknowledged !== true) {
throw new Error('error-failed-to-delete-department');
}
const removedAgents = await LivechatDepartmentAgents.findByDepartmentId(department._id, { projection: { agentId: 1 } }).toArray();
const actions = ['Removing department agents', 'Unsetting fallback department', 'Removing department from rooms'];
livechatLogger.debug({
msg: 'Post department removal actions',
departmentId: _id,
actions,
});
const promiseResponses = await Promise.allSettled([
LivechatDepartmentAgents.removeByDepartmentId(_id),
LivechatDepartment.unsetFallbackDepartmentByDepartmentId(_id),
LivechatRooms.bulkRemoveDepartmentAndUnitsFromRooms(_id),
]);
promiseResponses.forEach((response, index) => {View on GitHub (pinned to b2c16d5842)
Solutions
- Retry `removeDepartment` after verifying the department still exists (the delete may or may not have landed)
- Check MongoDB health and write concern configuration (avoid w:0 for control-plane writes)
- Inspect server logs/mongod for the write outcome; if the document persists, retry usually succeeds once the connection stabilizes
Example fix
// before
await removeDepartment(depId);
// after
for (let attempt = 1; attempt <= 3; attempt++) {
try {
await removeDepartment(depId);
break;
} catch (e) {
if (e.message !== 'error-failed-to-delete-department' || attempt === 3) throw e;
await LivechatDepartment.findOneById(depId, { projection: { _id: 1 } }).then((d) => !d && break);
}
} Defensive patterns
Strategy: retry
Validate before calling
// Not a payload problem — pre-check connection health instead
const ping = await LivechatDepartment.findOneById(depId, { projection: { _id: 1 } });
if (!ping) return; // already gone — nothing to delete Try / catch
let lastErr: unknown;
for (let i = 0; i < 3; i++) {
try {
await removeDepartment(depId);
lastErr = undefined;
break;
} catch (e) {
if (e instanceof Error && e.message !== 'error-failed-to-delete-department') throw e;
lastErr = e;
}
}
if (lastErr) throw lastErr; Prevention
- Use acknowledged write concerns (never w:0) for control-plane deletes
- Monitor MongoDB connectivity; unacknowledged writes cluster with connection flaps
- Verify post-retry that the department actually disappeared
When it happens
Trigger: MongoDB connection instability at the moment of the delete, a write concern configured without acknowledgement (w: 0), or a driver/server version quirk returning acknowledged:false — the department lookup succeeded, so the document existed an instant earlier.
Common situations: Self-hosted MongoDB behind flaky networking; replica set step-down during the delete; aggressive connection-pool recycling; custom write-concern settings.
Related errors
- error-forwarding-department-target-not-allowed
- error-not-authorized
- error-invalid-visitor
- error-removing-visitor
- error-room-cannot-be-closed-try-again
AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18).
Data as JSON: /api/errors/d5745af3a2037faf.
Report an issue: GitHub.