{"record":{"id":"406f70d46986eb02","repo":"gitroomhq/postiz-app","slug":"token-request-failed-error","errorCode":null,"errorMessage":"Token request failed: ${error}","messagePattern":"Token request failed: (.+?)","errorType":"error_code","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"apps/backend/src/services/auth/providers/apple.provider.ts","lineNumber":94,"sourceCode":"\n    const { clientId } = getConfig();\n    const response = await fetch('https://appleid.apple.com/auth/token', {\n      method: 'POST',\n      headers: {\n        'Content-Type': 'application/x-www-form-urlencoded',\n      },\n      body: new URLSearchParams({\n        grant_type: 'authorization_code',\n        code,\n        redirect_uri: redirectUri || defaultRedirect(),\n        client_id: clientId,\n        client_secret: clientSecret(),\n      }).toString(),\n    });\n\n    if (!response.ok) {\n      const error = await response.text();\n      throw new Error(`Token request failed: ${error}`);\n    }\n\n    const { id_token } = await response.json();\n    if (!id_token) {\n      throw new Error('Invalid provider token');\n    }\n\n    return id_token;\n  }\n\n  async getUser(providerToken: string) {\n    const { clientId } = getConfig();\n    const decoded = decode(providerToken, { complete: true });\n    const { keys } = await (\n      await fetch('https://appleid.apple.com/auth/keys')\n    ).json();\n\n    const key = keys.find(","sourceCodeStart":76,"sourceCodeEnd":112,"githubUrl":"https://github.com/gitroomhq/postiz-app/blob/0f1647f7491a217d43eb5ae7a480484bdf0aff3e/apps/backend/src/services/auth/providers/apple.provider.ts#L76-L112","documentation":"Apple's token endpoint (appleid.apple.com/auth/token) returned a non-2xx response while exchanging the authorization code for an id_token. The response body is embedded in the message, and Apple's body typically contains an error field such as invalid_client or invalid_grant.","triggerScenarios":"POST to Apple's token endpoint with an invalid/expired authorization code, wrong client_id, malformed or expired client_secret JWT (the .p8 key secret signed with the wrong key id, team id, or audience), or a redirect_uri mismatch.","commonSituations":"APPLE_TEAM_ID / APPLE_KEY_ID / APPLE_PRIVATE_KEY / APPLE_CLIENT_ID env vars misconfigured; the signed client_secret JWT passed its 6-month expiry or uses a bad .p8; authorization codes reused (they're single-use, ~5 min TTL); redirect_uri not registered in Apple developer console.","solutions":["Read the appended Apple error text: invalid_client -> fix client_secret generation (key id, team id, .p8, audience https://appleid.apple.com); invalid_grant -> code expired or reused, restart the sign-in flow","Verify APPLE_CLIENT_ID (Services ID for web) matches what's registered in the Apple developer console","Confirm redirect_uri in the token request exactly matches the one configured on the Apple Services ID","Generate a fresh client_secret JWT and confirm its exp is within 6 months and iat is not in the future (clock skew)"],"exampleFix":"// before\nconst clientSecret = jwt.sign(payload, oldKey, { header: { kid: oldKid } });\n\n// after\nconst clientSecret = jwt.sign(\n  { iss: process.env.APPLE_TEAM_ID, aud: 'https://appleid.apple.com', sub: clientId },\n  process.env.APPLE_PRIVATE_KEY,\n  { algorithm: 'ES256', expiresIn: '1h', header: { kid: process.env.APPLE_KEY_ID } }\n);","handlingStrategy":"try-catch","validationCode":"null","typeGuard":"null","tryCatchPattern":"try {\n  const token = await appleProvider.getToken(code);\n} catch (e) {\n  if (e instanceof Error && e.message.startsWith('Token request failed:')) {\n    const body = e.message.slice('Token request failed:'.length);\n    if (body.includes('invalid_grant')) return restartFlow(); // code expired/used\n    throw new ConfigurationError('Apple client credentials', body);\n  }\n  throw e;\n}","preventionTips":["Validate APPLE_TEAM_ID/KEY_ID/PRIVATE_KEY/CLIENT_ID at boot","Never reuse an Apple authorization code; exchange it immediately","Regenerate the ES256 client_secret with correct kid and aud"],"tags":["oauth","apple","token-exchange","provider"],"backgroundTag":"oauth-token-exchange-failed","analyzedSha":"0f1647f7491a217d43eb5ae7a480484bdf0aff3e","analyzedAt":"2026-08-27T12:09:55.020Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}