RocketChat/Rocket.Chat · error · Meteor.Error

error-field-unavailable

error-field-unavailable

Error message

<strong>${_.escape(username)}</strong> is already in use :(

What it means

checkUsernameAvailability() returned false: either another user already holds the name case-insensitively (Users.findOneByUsernameIgnoringCase) or a team is named the same (Team.getOneByName). Note the sibling case: names on Accounts_BlockedUsernameList (plus 'all'/'here') or Accounts_SystemBlockedUsernameList throw error-blocked-username instead — this error specifically means 'someone else owns it'.

Source

Thrown at apps/meteor/server/lib/users/setUsername.ts:64

	}

	if (user.username && !settings.get('Accounts_AllowUsernameChange')) {
		throw new Meteor.Error('error-not-allowed', 'Not allowed');
	}

	if (user.username === username || (user.username && user.username.toLowerCase() === username.toLowerCase())) {
		return;
	}

	if (!validateUsername(username)) {
		throw new Meteor.Error(
			'username-invalid',
			`${_.escape(username)} is not a valid username, use only letters, numbers, dots, hyphens and underscores`,
		);
	}

	if (!(await checkUsernameAvailability(username))) {
		throw new Meteor.Error('error-field-unavailable', `<strong>${_.escape(username)}</strong> is already in use :(`, {
			method: 'setUsername',
			field: username,
		});
	}

	if (!(await saveUserIdentity({ _id: user._id, username }))) {
		throw new Meteor.Error('error-could-not-change-username', 'Could not change username', {
			method: 'setUsername',
		});
	}

	if (!user.username) {
		await joinDefaultChannels(user._id, joinDefaultChannelsSilenced);
		setImmediate(async () => callbacks.run('afterCreateUser', user));
	}

	void notifyOnUserChange({ clientAction: 'updated', id: user._id, diff: { username } });
};

View on GitHub (pinned to b2c16d5842)

Solutions

  1. Choose a different name (the UI should suggest alternatives like name+number)
  2. Pre-check with checkUsernameAvailabilityWithValidation while the user types to fail fast
  3. If the name belongs to a deactivated/old account, an admin must rename or delete that account to free the name

Example fix

// before
await setUsernameWithValidation(userId, 'john'); // error-field-unavailable

// after
if (!(await checkUsernameAvailability('john'))) {
  throw new Meteor.Error('error-field-unavailable', 'john is already in use');
}
await setUsernameWithValidation(userId, 'john');
Defensive patterns

Strategy: validation

Validate before calling

import { checkUsernameAvailabilityWithValidation } from './checkUsernameAvailability';

const available = await checkUsernameAvailabilityWithValidation(userId, username);
if (!available) {
  // prompt for a different name before calling the save method
}

Try / catch

try {
  await setUsernameWithValidation(userId, username);
} catch (error) {
  if (error instanceof Meteor.Error && error.error === 'error-field-unavailable') {
    const taken = (error.details as { field?: string } | undefined)?.field;
    // mark the input as taken and keep the form open
  } else {
    throw error;
  }
}

Prevention

When it happens

Trigger: Submitting a username identical (ignoring case) to an existing user's or a team's name; casing-only changes to a name owned by someone else; a registration callback (checkUsernameAvailabilityCallback) rejecting the name.

Common situations: Self-service signup collisions ('mike', 'admin', 'john.smith'); users and teams sharing one namespace so a team name blocks a user name; migrations importing users with conflicting handles.

Related errors


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