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).

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.

Appendix: 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)