RocketChat/Rocket.Chat · error · Meteor.Error

error-invalid-user-id

error-invalid-user-id

Error message

Invalid user id

What it means

Thrown by the logout-other-clients endpoint after hashing the supplied x-auth-token, when Users.removeNonPATLoginTokensExcept(userId, hashedToken) returns falsy. The current token is not present in the user's resume tokens, so the 'keep this one, remove the rest' operation matched nothing.

Source

Thrown at apps/meteor/server/api/v1/users.ts:1649

						tokenExpires: { type: 'string' },
						success: { type: 'boolean', enum: [true] },
					},
					required: ['token', 'tokenExpires', 'success'],
					additionalProperties: false,
				}),
				401: validateUnauthorizedErrorResponse,
			},
		},
		async function action() {
			const xAuthToken = this.request.headers.get('x-auth-token') as string;

			if (!xAuthToken) {
				throw new Meteor.Error('error-parameter-required', 'x-auth-token is required');
			}
			const hashedToken = Accounts._hashLoginToken(xAuthToken);

			if (!(await Users.removeNonPATLoginTokensExcept(this.userId, hashedToken))) {
				throw new Meteor.Error('error-invalid-user-id', 'Invalid user id');
			}

			const me = (await Users.findOneById(this.userId, { projection: { 'services.resume.loginTokens': 1 } })) as Pick<IUser, 'services'>;

			void notifyOnUserChange({
				clientAction: 'updated',
				id: this.userId,
				diff: { 'services.resume.loginTokens': me.services?.resume?.loginTokens },
			});

			const token = me.services?.resume?.loginTokens?.find((token) => token.hashedToken === hashedToken);

			const loginExp = settings.get<number>('Accounts_LoginExpiration');

			const tokenExpires = (token && 'when' in token && new Date(token.when.getTime() + getLoginExpirationInMs(loginExp))) || undefined;

			return API.v1.success({
				token: xAuthToken,

View on GitHub (pinned to f9d3ec372b)

Solutions

  1. Re-authenticate and pass the current, valid login token in x-auth-token.
  2. Do not pass a Personal Access Token here; use a resume login token instead.
  3. If the token is valid but still fails, check the user's services.resume.loginTokens for the matching hashedToken.

Example fix

null
Defensive patterns

Strategy: retry

Validate before calling

// Re-authenticate if the stored token is stale
const valid = await GET('me');
if (!valid) { await reAuthenticate(); }
await POST('users.logoutOtherClients', {}, { headers: { 'x-auth-token': token } });

Type guard

null

Try / catch

try {
  await POST('users.logoutOtherClients', {}, { headers: { 'x-auth-token': token } });
} catch (e) {
  if (isMeteorError(e, 'error-invalid-user-id')) {
    // token no longer matches a session; log in again and retry once
    await reAuthenticate();
  } else { throw e; }
}

Prevention

When it happens

Trigger: POST users.logoutOtherClients with an x-auth-token that is not in the user's services.resume.loginTokens (already revoked, or a PAT which is excluded).

Common situations: Token already logged out; token belongs to a different session/user; using a Personal Access Token in x-auth-token; stale client state.

Related errors


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