RocketChat/Rocket.Chat · error · Meteor.Error

error-invalid-user

error-invalid-user

Error message

Invalid user

What it means

The 'addOAuthService' DDP method resolves the caller via Meteor.userId(); a null value (anonymous connection or expired/revoked login token) throws error-invalid-user before the permission check runs. Standard unauthenticated-call guard; the method is deprecated in favor of POST /v1/settings.addCustomOAuth which authenticates via X-Auth-Token/X-User-Id headers.

Source

Thrown at apps/meteor/server/meteor-methods/auth/addOAuthService.ts:35

	if ((await hasPermissionAsync(userId, 'add-oauth-service')) !== true) {
		throw new Meteor.Error('error-action-not-allowed', 'Adding OAuth Services is not allowed', {
			method: 'addOAuthService',
			action: 'Adding_OAuth_Services',
		});
	}

	await addOAuthService(name);
};

Meteor.methods<ServerMethods>({
	async addOAuthService(name) {
		methodDeprecationLogger.method('addOAuthService', '9.0.0', '/v1/settings.addCustomOAuth');
		check(name, String);

		const userId = Meteor.userId();

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

		return addOAuthServiceMethod(userId, name);
	},
});

View on GitHub (pinned to b2c16d5842)

Solutions

  1. Log in first (Meteor.loginWithToken or accounts login) and retry the method call.
  2. Use POST /api/v1/settings.addCustomOAuth with an admin token for scripted OAuth setup.
  3. Handle token expiry by re-authenticating instead of retrying blindly.

Example fix

// before: anonymous DDP connection
Meteor.call('addOAuthService', 'nextcloud');

// after: authenticated REST call
await fetch('/api/v1/settings.addCustomOAuth', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json', 'X-Auth-Token': authToken, 'X-User-Id': uid },
  body: JSON.stringify({ name: 'nextcloud' }),
});
Defensive patterns

Strategy: validation

Validate before calling

const uid = Meteor.userId();
if (!uid) {
  await reauthenticate(); // login or loginWithToken before privileged method calls
}
Meteor.call('addOAuthService', name);

Try / catch

try {
  await Meteor.callAsync('addOAuthService', name);
} catch (err: any) {
  if (err?.error === 'error-invalid-user' && err?.details?.method === 'addOAuthService') {
    await reauthenticate();
    return Meteor.callAsync('addOAuthService', name);
  }
  throw err;
}

Prevention

When it happens

Trigger: Meteor.call('addOAuthService', name) on a DDP connection without a valid login session; a resume token invalidated by logout-all while the socket stayed open; setup scripts driving DDP without ever logging in.

Common situations: Automation that opens a DDP socket but skips the Accounts login step; expired resume tokens in long-lived tooling; custom clients that bypass the login flow.

Related errors


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