{"record":{"id":"18de0c161b5b76ba","repo":"pnpm/pnpm","slug":"id-token-github-invalid-response","errorCode":"ID_TOKEN_GITHUB_INVALID_RESPONSE","errorMessage":"Failed to fetch idToken from GitHub: received an invalid response","messagePattern":"Failed to fetch idToken from GitHub: received an invalid response","errorType":"exception","errorClass":"IdTokenGitHubInvalidResponseError","httpStatus":null,"severity":"error","filePath":"pnpm11/releasing/commands/src/publish/oidc/idToken.ts","lineNumber":126,"sourceCode":"    headers: {\n      Accept: 'application/json',\n      Authorization: `Bearer ${env.ACTIONS_ID_TOKEN_REQUEST_TOKEN}`,\n    },\n    method: 'GET',\n    retry: {\n      factor: options?.fetchRetryFactor,\n      maxTimeout: options?.fetchRetryMaxtimeout,\n      minTimeout: options?.fetchRetryMintimeout,\n      retries: options?.fetchRetries,\n    },\n    timeout: options?.fetchTimeout,\n  })\n\n  const elapsedTime = Date.now() - startTime\n  globalInfo(`GET ${url.href} ${response.status} ${elapsedTime}ms`)\n\n  if (!response.ok) {\n    throw new IdTokenGitHubInvalidResponseError()\n  }\n\n  let json: unknown\n  try {\n    json = await response.json()\n  } catch (error) {\n    throw new IdTokenGitHubJsonInterruptedError(error)\n  }\n\n  if (!json || typeof json !== 'object' || !('value' in json) || typeof json.value !== 'string') {\n    throw new IdTokenGitHubJsonInvalidValueError(json)\n  }\n\n  return json.value\n}\n\nexport abstract class IdTokenError extends PnpmError {}\n","sourceCodeStart":108,"sourceCodeEnd":144,"githubUrl":"https://github.com/pnpm/pnpm/blob/6261b7f388016d57ca6b90340342411cd1d0d00f/pnpm11/releasing/commands/src/publish/oidc/idToken.ts#L108-L144","documentation":"The GET to GitHub's OIDC token endpoint ($ACTIONS_ID_TOKEN_REQUEST_URL with audience=npm:<registry-host>) completed with a non-ok HTTP status. The log line pnpm prints just before the throw (GET <url> <status> <elapsed>ms) carries the exact status: 400 usually means a malformed request/audience, 403 an expired or invalid request token (the env vars are single-job and go stale when reused).","triggerScenarios":"The ACTIONS_ID_TOKEN_* env vars were captured in one job and re-used in another (the token is short-lived and job-scoped); a tampered audience query; transient GitHub-side 5xx.","commonSituations":"Workflows that pass the OIDC env vars between jobs or cache them; rare GitHub outages; manual re-running of a step after the request token expired.","solutions":["Check the `GET ... <status>` log line printed above the error for the concrete status code","Re-run the workflow — 5xx responses from the token endpoint are transient","Run the pnpm publish step in the same job where the OIDC env vars were minted; never pass or cache them across jobs","If publishing to a custom registry, verify its hostname — the audience is derived from it as npm:<host>"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  await publish(pkg)\n} catch (err) {\n  if ((err as any).code === 'ID_TOKEN_GITHUB_INVALID_RESPONSE') {\n    // the `GET <url> <status> <ms>` log line above names the status:\n    // 403 => stale ACTIONS_ID_TOKEN vars (re-run in-job), 5xx => transient (re-run workflow)\n    throw err\n  }\n}","preventionTips":["Never persist or pass ACTIONS_ID_TOKEN_* env vars between jobs — they are minted per job","Keep the publish step in the same job that checks out and builds, so the OIDC vars are fresh"],"tags":["publish","oidc","github-actions","http-error","provenance"],"backgroundTag":"oidc-token-request-failed","analyzedSha":"6261b7f388016d57ca6b90340342411cd1d0d00f","analyzedAt":"2026-08-17T18:30:54.750Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}