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
- Log in first (Meteor.loginWithToken or accounts login) and retry the method call.
- Use POST /api/v1/settings.addCustomOAuth with an admin token for scripted OAuth setup.
- 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
- Complete the DDP login handshake before invoking admin methods.
- Use REST with header auth for scripts; tokens are explicit and auditable.
- Watch for logout-all / token revocation invalidating long-lived connections.
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.