RocketChat/Rocket.Chat · error · Meteor.Error

error-not-allowed

error-not-allowed

Error message

Not allowed

What it means

setUserStatusMethod rejects status-message updates when Accounts_AllowUserStatusMessageChange is false. The guard is statusText != null, so ANY non-null statusText - including the empty string '' - throws while the setting is off; only undefined/null slips past.

Solutions

  1. Omit statusText entirely (leave it undefined, not '') when the setting is disabled
  2. Enable Accounts_AllowUserStatusMessageChange if status messages should be allowed
  3. Hide the status-message input when the setting is false

Example fix

// before
Meteor.call('setUserStatus', statusType, statusText); // statusText may be ''

// after
const payload = allowStatusMessage && statusText != null
  ? { statusType, statusText }
  : { statusType };
Meteor.call('setUserStatus', payload.statusType, payload.statusText);
Defensive patterns

Strategy: validation

Validate before calling

const allowStatusMessage = publicSettings['Accounts_AllowUserStatusMessageChange'] === true;
const payload = allowStatusMessage && statusText != null
  ? { statusType, statusText }
  : { statusType };
Meteor.call('setUserStatus', payload.statusType, payload.statusText);

Type guard

const isStatusMessage = (v: unknown, allowed: boolean): v is string | undefined =>
  !allowed ? v === undefined : v === undefined || typeof v === 'string';

Try / catch

catch (err) {
  if (err instanceof Meteor.Error && err.error === 'error-not-allowed') {
    showNotice('Status messages are disabled on this server');
  }
}

Prevention

When it happens

Trigger: Meteor.call('setUserStatus', statusType, statusText) or a saveUserProfile submit with statusText: '' (a common 'clear message' pattern) on a workspace where Accounts_AllowUserStatusMessageChange is disabled.

Common situations: Default installs with status messages off; client UIs that send an empty string when clearing a status message; profile-save flows that always include statusText even when the user never touched it.

Related errors


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

Appendix: source

Thrown at apps/meteor/server/meteor-methods/users/setUserStatus.ts:22

import { Meteor } from 'meteor/meteor';

import { RateLimiterClass as RateLimiter } from '../../lib/RateLimiter';
import { settings } from '../../settings';

declare module '@rocket.chat/ddp-client' {
	// eslint-disable-next-line @typescript-eslint/naming-convention
	interface ServerMethods {
		setUserStatus(statusType: IUser['status'], statusText: IUser['statusText']): void;
	}
}

export const setUserStatusMethod = async (
	user: Pick<IUser, '_id' | 'username' | 'name' | 'status' | 'statusDefault' | 'roles' | 'statusText'>,
	statusType: IUser['status'],
	statusText: IUser['statusText'],
): Promise<void> => {
	if (statusText != null && !settings.get('Accounts_AllowUserStatusMessageChange')) {
		throw new Meteor.Error('error-not-allowed', 'Not allowed', {
			method: 'setUserStatus',
		});
	}

	const effectiveStatus = statusType || user.statusDefault || UserStatus.ONLINE;

	if (effectiveStatus === UserStatus.OFFLINE && !settings.get('Accounts_AllowInvisibleStatusOption')) {
		throw new Meteor.Error('error-status-not-allowed', 'Invisible status is disabled', {
			method: 'setUserStatus',
		});
	}

	await Presence.setStatus(user._id, effectiveStatus, statusText);
};

Meteor.methods<ServerMethods>({
	setUserStatus: async (statusType, statusText) => {
		const user = (await Meteor.userAsync()) as IUser;

View on GitHub (pinned to b2c16d5842)