{"record":{"id":"99ee937238235593","repo":"gitroomhq/postiz-app","slug":"invalid-token-99ee93","errorCode":"invalid_token","errorMessage":"{ error: 'invalid_token', error_description: 'Bearer token required' }","messagePattern":"\\{ error: 'invalid_token', error_description: 'Bearer token required' \\}","errorType":"http","errorClass":"HttpException","httpStatus":401,"severity":"error","filePath":"libraries/nestjs-libraries/src/database/prisma/oauth/oauth.service.ts","lineNumber":355,"sourceCode":"  async getOrgByOAuthToken(token: string) {\n    const encrypted = AuthService.fixedEncryption(token);\n    return this._oauthRepository.findByAccessToken(encrypted);\n  }\n\n  async getUserInfo(authorization?: string) {\n    if (!enableOidcEmailClaims()) {\n      throw new HttpException(\n        {\n          error: 'not_found',\n          error_description: 'OIDC email claims are not enabled',\n        },\n        HttpStatus.NOT_FOUND\n      );\n    }\n\n    const token = extractBearerToken(authorization);\n    if (!token) {\n      throw new HttpException(\n        { error: 'invalid_token', error_description: 'Bearer token required' },\n        HttpStatus.UNAUTHORIZED\n      );\n    }\n\n    const authorizationRecord = await this.getOrgByOAuthToken(token);\n    if (!authorizationRecord) {\n      throw new HttpException(\n        { error: 'invalid_token', error_description: 'Token is invalid or revoked' },\n        HttpStatus.UNAUTHORIZED\n      );\n    }\n\n    if (authorizationRecord.oauthApp.clientId !== openAiOAuthClientId()) {\n      throw new HttpException(\n        {\n          error: 'insufficient_scope',\n          error_description:","sourceCodeStart":337,"sourceCodeEnd":373,"githubUrl":"https://github.com/gitroomhq/postiz-app/blob/0f1647f7491a217d43eb5ae7a480484bdf0aff3e/libraries/nestjs-libraries/src/database/prisma/oauth/oauth.service.ts#L337-L373","documentation":"Returned as HTTP 401 invalid_token from getUserInfo when the Authorization header is missing or does not contain a valid Bearer token (extractBearerToken returns null). The endpoint requires 'Authorization: Bearer <token>'.","triggerScenarios":"Calling the user info endpoint with no Authorization header, a non-Bearer scheme (Basic, token), an empty token, or a malformed header like 'Bearer' with no value.","commonSituations":"Client reads the token from the wrong JSON field (e.g. access_token vs id_token); token not persisted between requests; header built manually with typos; passing the whole token response object instead of the string.","solutions":["Set the header exactly: Authorization: Bearer <accessToken>","Confirm you're using the access_token from the token exchange response (not id_token or code)","Check for 'Bearer ' prefix capitalization and single space, and that the token string isn't undefined"],"exampleFix":"// before\nfetch(userInfoEndpoint, { headers: { Authorization: tokens.id_token } });\n// after\nfetch(userInfoEndpoint, { headers: { Authorization: `Bearer ${tokens.access_token}` } });","handlingStrategy":"validation","validationCode":"const token = extractBearer(authorization);\nif (!token) throw new Error('Authorization: Bearer <access_token> header required');","typeGuard":"const hasBearerToken = (h?: string): boolean => /^Bearer \\S+$/.test(h ?? '');","tryCatchPattern":"try { return await getUserInfo(auth); } catch (e) { if (e?.response?.data?.error === 'invalid_token' && !auth?.startsWith('Bearer ')) { return getUserInfo(`Bearer ${auth}`); } throw e; }","preventionTips":["Build the header from tokens.access_token via a helper","Never pass id_token or the raw response object"],"tags":["oidc","userinfo","bearer-token","unauthorized"],"backgroundTag":"missing-bearer-token","analyzedSha":"0f1647f7491a217d43eb5ae7a480484bdf0aff3e","analyzedAt":"2026-08-27T12:09:55.020Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}