RocketChat/Rocket.Chat · error · Meteor.Error
error-not-allowed
error-not-allowed
Error message
Not allowed
What it means
The deleteOAuthApp helper checks the 'manage-oauth-apps' permission for the calling userId and throws 'error-not-allowed' when absent, before any lookup happens. The Meteor method is deprecated since 9.0.0 in favor of DELETE /api/v1/oauth-apps.delete, which performs the same permission gate.
Source
Thrown at apps/meteor/server/meteor-methods/auth/deleteOAuthApp.ts:18
import type { IOAuthApps } from '@rocket.chat/core-typings';
import type { ServerMethods } from '@rocket.chat/ddp-client';
import { OAuthAccessTokens, OAuthApps, OAuthAuthCodes } from '@rocket.chat/models';
import { Meteor } from 'meteor/meteor';
import { hasPermissionAsync } from '../../lib/authorization/hasPermission';
import { methodDeprecationLogger } from '../../lib/deprecationWarningLogger';
declare module '@rocket.chat/ddp-client' {
// eslint-disable-next-line @typescript-eslint/naming-convention
interface ServerMethods {
deleteOAuthApp(applicationId: IOAuthApps['_id']): boolean;
}
}
export const deleteOAuthApp = async (userId: string, applicationId: IOAuthApps['_id']): Promise<boolean> => {
if (!(await hasPermissionAsync(userId, 'manage-oauth-apps'))) {
throw new Meteor.Error('error-not-allowed', 'Not allowed', { method: 'deleteOAuthApp' });
}
const application = await OAuthApps.findOneAndDeleteById(applicationId, { projection: { clientId: 1 } });
if (!application) {
throw new Meteor.Error('error-application-not-found', 'Application not found', {
method: 'deleteOAuthApp',
});
}
await OAuthAccessTokens.deleteMany({ clientId: application.clientId });
await OAuthAuthCodes.deleteMany({ clientId: application.clientId });
return true;
};
Meteor.methods<ServerMethods>({
async deleteOAuthApp(applicationId) {
methodDeprecationLogger.method('deleteOAuthApp', '9.0.0', '/v1/oauth-apps.delete');View on GitHub (pinned to b2c16d5842)
Solutions
- Grant 'manage-oauth-apps' to the caller's role in the admin Permissions screen
- Migrate to DELETE /api/v1/oauth-apps.delete with a token whose user holds the permission
- Verify the effective permissions of the caller before retrying
Defensive patterns
Strategy: validation
Validate before calling
// server-side: check the permission before attempting the delete
import { hasPermissionAsync } from '../lib/authorization/hasPermission';
if (!(await hasPermissionAsync(userId, 'manage-oauth-apps'))) {
// reject in the UI instead of triggering the server error
} Try / catch
try {
await Meteor.callAsync('deleteOAuthApp', applicationId);
} catch (err) {
if (err instanceof Meteor.Error && err.error === 'error-not-allowed') {
// caller lacks 'manage-oauth-apps': grant it or use an authorized token
}
} Prevention
- Gate the delete action on hasPermission('manage-oauth-apps')
- Prefer DELETE /api/v1/oauth-apps.delete with an authorized token over the deprecated method
When it happens
Trigger: Calling deleteOAuthApp as a user whose roles do not include 'manage-oauth-apps'; using a custom integration role that was never granted the permission.
Common situations: Delegating OAuth app management to a sub-admin role that lacks the grant; the permission was removed from the role during a permissions audit.
Understand the failure class
Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.
Related errors
- error-invalid-user
- error-invalid-role
- error-permission-not-found
- The required "roomId" or "roomName" param provided does not
- error-action-not-allowed
AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18).
Data as JSON: /api/errors/090ec425a386e3a8.
Report an issue: GitHub.