{"record":{"id":"341d6cfd4ba83a42","repo":"gitroomhq/postiz-app","slug":"invalid-user","errorCode":null,"errorMessage":"Invalid user","messagePattern":"Invalid user","errorType":"error_code","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"apps/backend/src/services/auth/auth.service.ts","lineNumber":317,"sourceCode":"    redirectUri?: string,\n    state?: string,\n    stateCookie?: string\n  ) {\n    // the mobile app passes redirect_uri and keeps no cookies, the web flow\n    // never passes it, so the state nonce is only enforced for the web flow\n    if (\n      !process.env.NOT_SECURED &&\n      !redirectUri &&\n      (!state || state !== stateCookie)\n    ) {\n      throw new Error('Invalid state');\n    }\n\n    const providerInstance = this._providerManager.getProvider(provider);\n    const token = await providerInstance.getToken(code, redirectUri);\n    const user = await providerInstance.getUser(token);\n    if (!user) {\n      throw new Error('Invalid user');\n    }\n    const checkExists = await this._userService.getUserByProvider(\n      user.id,\n      provider as Provider\n    );\n    if (checkExists) {\n      return { jwt: await this.jwt(checkExists) };\n    }\n\n    return { token };\n  }\n\n  private async jwt(user: User) {\n    if (user.password) {\n      delete user.password;\n    }\n    return AuthChecker.signJWT(user);\n  }","sourceCodeStart":299,"sourceCodeEnd":335,"githubUrl":"https://github.com/gitroomhq/postiz-app/blob/0f1647f7491a217d43eb5ae7a480484bdf0aff3e/apps/backend/src/services/auth/auth.service.ts#L299-L335","documentation":"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).","triggerScenarios":"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.","commonSituations":"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.","solutions":["Inspect what getUser(token) actually returns for the failing provider (log the raw provider response)","Verify the OAuth app's granted scopes include profile/email access","Confirm the provider client ID/secret correspond to the app whose users are logging in","Retry once — transient provider userinfo failures do occur","Check the provider's status page / API changelog if it persists"],"exampleFix":"// before\nconst user = await providerInstance.getUser(token);\n\n// after — surface provider payload for diagnosis\nconst raw = await providerInstance.getUser(token);\nif (!raw) {\n  throw new Error(\n    `Invalid user: provider ${provider} returned empty profile for token`\n  );\n}","handlingStrategy":"retry","validationCode":"null","typeGuard":"const isProviderUser = (u: unknown): u is { email: string; id: string } =>\n  typeof u === 'object' && u !== null &&\n  typeof (u as any).email === 'string' && typeof (u as any).id === 'string';","tryCatchPattern":"try {\n  await authService.checkExists(params);\n} catch (e) {\n  if (e instanceof Error && e.message === 'Invalid user') {\n    // transient provider userinfo failure: restart flow once\n    return redirectToLogin();\n  }\n  throw e;\n}","preventionTips":["Request openid/email scopes in every provider config","Retry once on provider userinfo failures before surfacing to the user","Log raw provider responses to diagnose shape changes early"],"tags":["oauth","provider","user-info"],"backgroundTag":"oauth-userinfo-empty","analyzedSha":"0f1647f7491a217d43eb5ae7a480484bdf0aff3e","analyzedAt":"2026-08-27T12:09:55.020Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}