RocketChat/Rocket.Chat · error

error-invalid-user

error-invalid-user

Error message

error-invalid-user

What it means

Error `error-invalid-user` thrown by ldap.syncNow when this.userId is falsy inside the action. The route declares authRequired (plus 2FA enforcement for non-EE), so in practice this fires only when authentication state is missing/inconsistent — e.g. broken auth middleware, token accepted but no user bound, or direct invocation bypassing the API wrapper.

Solutions

  1. Send valid X-Auth-Token and X-User-Id headers from a real, active admin user.
  2. Re-login to mint a fresh token if the user was recreated or the token expired.
  3. If it persists with valid credentials, inspect custom auth middleware that may strip the user from the context.

Example fix

// before
await fetch('/api/v1/ldap.syncNow', { method: 'POST' }); // error-invalid-user

// after
await fetch('/api/v1/ldap.syncNow', {
	method: 'POST',
	headers: { 'X-Auth-Token': token, 'X-User-Id': userId, 'Content-Type': 'application/json' },
});
Defensive patterns

Strategy: validation

Validate before calling

const hasAuthContext = (userId: string | null | undefined): boolean => Boolean(userId);

// ensure headers on every request
const headers = { 'X-Auth-Token': authToken, 'X-User-Id': userId };

Type guard

const isInvalidUserError = (error: unknown): boolean =>
	Boolean(error && typeof error === 'object' && 'message' in error && (error as Error).message.includes('error-invalid-user'));

Try / catch

try {
	await POST('ldap.syncNow');
} catch (error) {
	if (isInvalidUserError(error)) {
		await relogin(); // mint fresh credentials, then retry once
		return POST('ldap.syncNow');
	}
	throw error;
}

Prevention

When it happens

Trigger: Calling POST /v1/ldap.syncNow without an auth token, with a token for a deleted user, or through a code path that invokes the action without the auth context populated.

Common situations: Scripts forgetting the X-Auth-Token/X-User-Id headers; tokens invalidated between auth and handler; tests invoking the endpoint handler directly.

Understand the failure class

Background: error-invalid-user: "Invalid user" errors in Rocket.Chat — what they mean and how to fix them — this error's family across 2 libraries.

Related errors


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

Appendix: source

Thrown at apps/meteor/ee/server/api/ldap.ts:32

	required: ['message', 'success'],
	additionalProperties: false,
});

API.v1.post(
	'ldap.syncNow',
	{
		authRequired: true,
		forceTwoFactorAuthenticationForNonEnterprise: true,
		twoFactorRequired: true,
		response: {
			200: ldapSyncNowResponseSchema,
			400: validateBadRequestErrorResponse,
			401: validateUnauthorizedErrorResponse,
		},
	},
	async function action() {
		if (!this.userId) {
			throw new Error('error-invalid-user');
		}

		if (!(await hasPermissionAsync(this.user, 'sync-auth-services-users'))) {
			throw new Error('error-not-authorized');
		}

		if (settings.get('LDAP_Enable') !== true) {
			throw new Error('LDAP_disabled');
		}

		await LDAPEnterprise.sync();
		await LDAPEnterprise.syncAvatarAndAbacAttributes();

		return API.v1.success({
			message: 'Sync_in_progress' as const,
		});
	},
);

View on GitHub (pinned to b2c16d5842)