RocketChat/Rocket.Chat · error · MeteorError

error-invalid-scope

error-invalid-scope

Error message

Invalid scope

What it means

Thrown by updateRole in updateRole.ts:38 when roleData.scope is supplied but isValidRoleScope returns false. Same validator as insert: scope must be 'Users' or 'Subscriptions'. MeteorError code 'error-invalid-scope'.

Source

Thrown at apps/meteor/ee/server/lib/roles/updateRole.ts:38

		throw new MeteorError('error-invalid-roleId', 'This role does not exist');
	}

	if (role.protected && ((roleData.name && roleData.name !== role.name) || (roleData.scope && roleData.scope !== role.scope))) {
		throw new MeteorError('error-role-protected', 'Role is protected');
	}

	if (roleData.name) {
		const otherRole = await Roles.findOneByName(roleData.name, { projection: { _id: 1 } });
		if (otherRole && otherRole._id !== role._id) {
			throw new MeteorError('error-duplicate-role-names-not-allowed', 'Role name already exists');
		}
	} else {
		roleData.name = role.name;
	}

	if (roleData.scope) {
		if (!isValidRoleScope(roleData.scope)) {
			throw new MeteorError('error-invalid-scope', 'Invalid scope');
		}
	} else {
		roleData.scope = role.scope;
	}

	await Roles.updateById(roleId, roleData.name, roleData.scope, roleData.description, roleData.mandatory2fa);

	void notifyOnRoleChangedById(roleId);

	if (options.broadcastUpdate) {
		void api.broadcast('user.roleUpdate', {
			type: 'changed',
			_id: roleId,
			scope: roleData.scope,
		});
	}

	const updatedRole = await Roles.findOneById(roleId);

View on GitHub (pinned to f9d3ec372b)

Solutions

  1. Set scope to 'Users' or 'Subscriptions', or omit it to keep the current value.
  2. Validate scope against the allowed enum before calling updateRole.
  3. Catch MeteorError 'error-invalid-scope' and re-prompt.

Example fix

// before
await updateRole(roleId, { scope: 'Rooms' });

// after
const VALID = ['Users', 'Subscriptions'] as const;
const patch = rawScope && !VALID.includes(rawScope) ? { scope: 'Users' } : { scope: rawScope };
await updateRole(roleId, patch);
Defensive patterns

Strategy: validation

Validate before calling

const VALID = ['Users', 'Subscriptions'] as const;
if (roleData.scope && !VALID.includes(roleData.scope as any)) throw new Error('invalid scope');

Type guard

const isValidScope = (scope: unknown): scope is 'Users' | 'Subscriptions' =>
  scope === 'Users' || scope === 'Subscriptions';

Try / catch

try { await updateRole(roleId, roleData); }
catch (e) {
  if (e?.code === 'error-invalid-scope') { /* re-prompt */ return; }
  throw e;
}

Prevention

When it happens

Trigger: Updating a role and passing a scope outside ['Users','Subscriptions']. Note: an empty/falsy scope is allowed (it falls through to roleData.scope = role.scope), only a non-empty invalid value triggers this.

Common situations: Caller passes scope: 'Rooms' or 'Global'; UI sends an empty-string scope that bypasses the falsy branch.

Related errors


AI-assisted analysis of RocketChat/Rocket.Chat@f9d3ec372b (2026-08-12). Data as JSON: /api/errors/175a76e5b4d30936. Report an issue: GitHub.