gitroomhq/postiz-app · error · Error

Invalid user

Error message

Invalid user

What it means

After exchanging the OAuth code for a token, the provider instance's getUser(token) returned a falsy user, so the identity could not be established. It means the provider accepted the token but the profile lookup yielded nothing (or returned a shape the code can't read).

Source

Thrown at apps/backend/src/services/auth/auth.service.ts:317

    redirectUri?: string,
    state?: string,
    stateCookie?: string
  ) {
    // the mobile app passes redirect_uri and keeps no cookies, the web flow
    // never passes it, so the state nonce is only enforced for the web flow
    if (
      !process.env.NOT_SECURED &&
      !redirectUri &&
      (!state || state !== stateCookie)
    ) {
      throw new Error('Invalid state');
    }

    const providerInstance = this._providerManager.getProvider(provider);
    const token = await providerInstance.getToken(code, redirectUri);
    const user = await providerInstance.getUser(token);
    if (!user) {
      throw new Error('Invalid user');
    }
    const checkExists = await this._userService.getUserByProvider(
      user.id,
      provider as Provider
    );
    if (checkExists) {
      return { jwt: await this.jwt(checkExists) };
    }

    return { token };
  }

  private async jwt(user: User) {
    if (user.password) {
      delete user.password;
    }
    return AuthChecker.signJWT(user);
  }

View on GitHub (pinned to 0f1647f749)

Solutions

  1. Inspect what getUser(token) actually returns for the failing provider (log the raw provider response)
  2. Verify the OAuth app's granted scopes include profile/email access
  3. Confirm the provider client ID/secret correspond to the app whose users are logging in
  4. Retry once — transient provider userinfo failures do occur
  5. Check the provider's status page / API changelog if it persists

Example fix

// before
const user = await providerInstance.getUser(token);

// after — surface provider payload for diagnosis
const raw = await providerInstance.getUser(token);
if (!raw) {
  throw new Error(
    `Invalid user: provider ${provider} returned empty profile for token`
  );
}
Defensive patterns

Strategy: retry

Validate before calling

null

Type guard

const isProviderUser = (u: unknown): u is { email: string; id: string } =>
  typeof u === 'object' && u !== null &&
  typeof (u as any).email === 'string' && typeof (u as any).id === 'string';

Try / catch

try {
  await authService.checkExists(params);
} catch (e) {
  if (e instanceof Error && e.message === 'Invalid user') {
    // transient provider userinfo failure: restart flow once
    return redirectToLogin();
  }
  throw e;
}

Prevention

When it happens

Trigger: OAuth code exchanged successfully but the provider's user-info endpoint returns empty/invalid payload; token scope missing profile/email access; provider API returned an error body that getUser parses into undefined; rate-limited or partially-failing provider response.

Common situations: Missing email scope on the OAuth app so email is undefined and downstream parsing fails; provider API outage or schema change; using a token whose scopes don't include userinfo; stale provider credentials pointing at the wrong app.

Related errors


AI-assisted analysis of gitroomhq/postiz-app@0f1647f749 (2026-08-27). Data as JSON: /api/errors/341d6cfd4ba83a42. Report an issue: GitHub.