RocketChat/Rocket.Chat · error · Meteor.Error

error-permission-not-found

error-permission-not-found

Error message

Permission not found

What it means

Thrown when removing a role from a permission whose permissionId resolves to no document in the Permissions collection. Reached via DDP 'authorization:removeRoleFromPermission' or 'POST /api/v1/permissions.removeRole'. Unlike the add path there is no role existence check here, so this error is purely about the permission id.

Source

Thrown at apps/meteor/server/lib/authorization/permissionRole.ts:61

			action: 'Adding_permission',
		});
	}

	if (permission.groupPermissionId) {
		await Permissions.addRole(permission.groupPermissionId, role);
		void notifyOnPermissionChangedById(permission.groupPermissionId);
	}

	await Permissions.addRole(permission._id, role);

	void notifyOnPermissionChangedById(permission._id);
};

export const removeRoleFromPermissionMethod = async (uid: string, permissionId: string, role: string): Promise<void> => {
	const permission = await Permissions.findOneById(permissionId);

	if (!permission) {
		throw new Meteor.Error('error-permission-not-found', 'Permission not found', {
			method: 'authorization:removeRoleFromPermission',
		});
	}

	if (
		!(await hasPermissionAsync(uid, 'access-permissions')) ||
		(permission.level === CONSTANTS.SETTINGS_LEVEL && !(await hasPermissionAsync(uid, 'access-setting-permissions')))
	) {
		throw new Meteor.Error('error-action-not-allowed', 'Removing permission is not allowed', {
			method: 'authorization:removeRoleFromPermission',
			action: 'Removing_permission',
		});
	}

	if (permission.groupPermissionId) {
		await Permissions.removeRole(permission.groupPermissionId, role);
		void notifyOnPermissionChangedById(permission.groupPermissionId);
	}

View on GitHub (pinned to b2c16d5842)

Solutions

  1. Reload the permissions list so the client resends current ids, then retry
  2. Verify the permissionId against the live permission list before calling
  3. In mixed-version deployments, finish upgrading all nodes before editing permissions
  4. If automating, fetch permission ids at runtime instead of persisting them
Defensive patterns

Strategy: validation

Validate before calling

const known = new Set((await fetchPermissionsList()).map((p) => p._id));
if (!known.has(permissionId)) {
  // refetch the permission list / abort instead of calling permissions.removeRole
}

Try / catch

try {
  await call('authorization:removeRoleFromPermission', permissionId, role);
} catch (e) {
  if (e instanceof Meteor.Error && e.error === 'error-permission-not-found') {
    // reload permissions metadata and retry once with fresh ids
  } else {
    throw e;
  }
}

Prevention

When it happens

Trigger: The permissions screen holds a permission id that a Rocket.Chat upgrade renamed or removed (permission definitions change between versions); a script posts permissions.removeRole with a stale or hardcoded permissionId; mixed-version cluster where nodes hold different permission documents.

Common situations: Editing permissions right after an upgrade without a page reload; server downgrades; workspace restores where the Permissions collection drifted from the version's expected permission ids.

Related errors


AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18). Data as JSON: /api/errors/f4410a64ba265787. Report an issue: GitHub.