RocketChat/Rocket.Chat · error · Meteor.Error
error-not-allowed
error-not-allowed
Error message
Not allowed
What it means
dmDeleteAction calls canAccessRoomIdAsync(room._id, userId) OR hasPermissionAsync(user, 'view-room-administration'). If both are false it throws error-not-allowed. Erasing a DM is therefore restricted to actual participants or workspace administrators with the view-room-administration permission.
Source
Thrown at apps/meteor/server/api/v1/im.ts:178
type: 'boolean',
enum: [true],
},
},
required: ['success'],
additionalProperties: false,
}),
},
};
const dmDeleteAction = <Path extends string>(_path: Path): TypedAction<typeof dmDeleteEndpointsProps, Path> =>
async function action() {
const { room } = await findDirectMessageRoom(this.bodyParams, this.userId);
const canAccess =
(await canAccessRoomIdAsync(room._id, this.userId)) || (await hasPermissionAsync(this.user, 'view-room-administration'));
if (!canAccess) {
throw new Meteor.Error('error-not-allowed', 'Not allowed');
}
await eraseRoom(room._id, this.user);
return API.v1.success();
};
const dmCloseAction = <Path extends string>(_path: Path): TypedAction<typeof dmCloseEndpointsProps, Path> =>
async function action() {
const { roomId } = this.bodyParams;
if (!roomId) {
throw new Meteor.Error('error-room-param-not-provided', 'Body param "roomId" is required');
}
if (!this.userId) {
throw new Meteor.Error('error-invalid-user', 'Invalid user', {
method: 'dm.close',
});
}View on GitHub (pinned to f9d3ec372b)
Solutions
- Call the endpoint as one of the two DM participants.
- Grant the calling role/token owner the 'view-room-administration' permission if administrative deletion is intended.
- Use an admin token (admin role) for cleanup automation.
- Verify the target roomId actually belongs to a DM the caller is in (im.list).
Example fix
// before: bot token with no admin rights
await POST /api/v1/im.delete { roomId } // -> error-not-allowed
// after: grant permission or use participant token
await POST /api/v1/im.delete { roomId } // called by a DM participant, or by a role with view-room-administration Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-check access without mutating
const me = await api.get('/api/v1/me');
const subs = await api.get('/api/v1/im.list');
const isParticipant = subs.data.ims.some(im => im._id === roomId);
const isAdmin = me.data.roles?.includes('admin');
if (!isParticipant && !isAdmin) throw new Error('Caller cannot delete this DM'); Try / catch
try {
await api.post('/api/v1/im.delete', { roomId });
} catch (e) {
if (e.response?.data?.error === 'error-not-allowed') {
// switch to a participant/admin token, or skip
} else throw e;
} Prevention
- Run deletion automation as a participant or a role holding view-room-administration.
- Audit the calling token's permissions before deployment.
- Do not assume any authenticated user can erase arbitrary DMs.
When it happens
Trigger: POST /api/v1/im.delete by a user who is neither a member of the target DM nor holds the 'view-room-administration' permission. Authenticated but unauthorized deletion attempt.
Common situations: A bot or integration trying to clean up DMs it did not create; a normal user attempting to delete another user's DM; permission 'view-room-administration' was revoked from the calling role.
Related errors
- error-room-not-found
- error-endpoint-disabled
- error-roomid-param-not-provided
- error-no-messages
- error-invalid-room
AI-assisted analysis of RocketChat/Rocket.Chat@f9d3ec372b (2026-08-12).
Data as JSON: /api/errors/0b7b341b3a93571f.
Report an issue: GitHub.