RocketChat/Rocket.Chat · error · Meteor.Error

error-invalid-user

error-invalid-user

Error message

Invalid user

What it means

Thrown by addIncomingIntegration when Users.findOneByUsername(integration.username) returns null: no user with that exact username exists in this workspace. Lookup happens before any permission checks on the target user, so a typo fails here rather than as a permission error. Usernames are matched exactly (case-sensitive) against the Users collection.

Source

Thrown at apps/meteor/server/meteor-methods/integrations/incoming/addIncomingIntegration.ts:88

				method: 'updateIncomingIntegration',
			});
		}
	}

	if (!integration.username || typeof integration.username.valueOf() !== 'string' || integration.username.trim() === '') {
		throw new Meteor.Error('error-invalid-username', 'Invalid username', {
			method: 'addIncomingIntegration',
		});
	}

	if (integration.script?.trim()) {
		validateScriptEngine(integration.scriptEngine ?? 'isolated-vm');
	}

	const user = await Users.findOneByUsername(integration.username, { projection: { _id: 1 } });

	if (!user) {
		throw new Meteor.Error('error-invalid-user', 'Invalid user', {
			method: 'addIncomingIntegration',
		});
	}

	if (!(await hasPermissionAsync(user._id, 'message-impersonate'))) {
		throw new Meteor.Error(
			'error-user-lacks-message-impersonate-permission',
			"User selected for the incoming integration lacks the 'message-impersonate' permission.",
			{
				method: 'addIncomingIntegration',
			},
		);
	}

	// Default to transpiling with Babel for backwards compatibility; integrations
	// can opt-out per-record by setting `skipTranspile: true` (removed in 9.0.0).
	const skipTranspile = integration.skipTranspile === true;

View on GitHub (pinned to b2c16d5842)

Solutions

  1. Copy the exact username from Administration -> Users (the @handle, not the display name)
  2. Create the bot user first (Administration -> Users -> New) and retry with its username
  3. If provisioning via API, verify with GET /api/v1/users.info?username=... before creating the integration

Example fix

// before
Meteor.callAsync('addIncomingIntegration', { ...integration, username: 'CI Bot' }); // display name -> no such user
// after
Meteor.callAsync('addIncomingIntegration', { ...integration, username: 'ci.bot' }); // exact username from Users admin
Defensive patterns

Strategy: validation

Validate before calling

// server-side / REST caller: confirm the user exists before the DDP/method call
const res = await fetch(`${root}/api/v1/users.info?username=${encodeURIComponent(integration.username)}`, { headers: authHeaders });
if (!res.ok) throw new Error(`post-as user '${integration.username}' does not exist`);
await Meteor.callAsync('addIncomingIntegration', integration);

Type guard

const isUsernameOfExistingUser = (username: string, known: { username: string }[]) => known.some((u) => u.username === username);

Try / catch

try {
  await Meteor.callAsync('addIncomingIntegration', integration);
} catch (err) {
  if (err instanceof Meteor.Error && err.error === 'error-invalid-user') { /* surface 'user not found', offer user picker */ }
}

Prevention

When it happens

Trigger: username: 'CI Bot' (display name instead of username), 'john.doe' after the user renamed to 'john.doe2', a user deleted from the workspace, or the account existing only on a different server/deployment.

Common situations: Copy-pasting the visible name from the UI instead of the @username; hard-coded bot username that was never provisioned on this environment; multi-environment configs where the bot exists in staging but not production.

Related errors


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