{"record":{"id":"415254065516ade0","repo":"can1357/oh-my-pi","slug":"the-pinned-security-oauth-credential-could-not-be","errorCode":null,"errorMessage":"The pinned security OAuth credential could not be resolved","messagePattern":"The pinned security OAuth credential could not be resolved","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/security/auth.ts","lineNumber":69,"sourceCode":"\t\t);\n\t}\n\tconst account: SecurityAccountRef = { provider, credentialId: selected.credentialId };\n\tif (selected.accountId !== undefined) account.accountId = selected.accountId;\n\tif (selected.email !== undefined) account.email = selected.email;\n\tif (selected.orgId !== undefined) account.organizationId = selected.orgId;\n\tif (selected.orgName !== undefined) account.organizationName = selected.orgName;\n\treturn account;\n}\n\nexport async function resolveExactSecurityOAuthAccess(\n\tauthStorage: AuthStorage,\n\taccount: SecurityAccountRef,\n\toptions: { forceRefresh: boolean; signal?: AbortSignal },\n): Promise<Extract<OAuthAccessResolution, { ok: true }>> {\n\tconst resolution = await authStorage.getOAuthAccessByCredentialId(account.provider, account.credentialId, options);\n\tif (!resolution) throw new Error(\"The pinned security OAuth credential is unavailable\");\n\tassertSecurityIdentityMatches(account, resolution);\n\tif (!resolution.ok) throw new Error(\"The pinned security OAuth credential could not be resolved\");\n\treturn resolution;\n}\n\n/**\n * Build a request credential resolver pinned to one durable OAuth row.\n *\n * Initial resolution and refresh both target the same row. The auth driver's\n * final sibling-rotation step returns `undefined`, so an unavailable account\n * fails the scan rather than crossing an account/workspace boundary.\n */\nexport function createExactSecurityOAuthResolver(\n\toptions: ExactSecurityOAuthOptions,\n): NonNullable<AgentOptions[\"getApiKey\"]> {\n\tconst { account, authStorage } = options;\n\treturn model => {\n\t\tif (model.provider !== account.provider) {\n\t\t\tthrow new Error(\"Security scan authentication provider mismatch\");\n\t\t}","sourceCodeStart":51,"sourceCodeEnd":87,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/security/auth.ts#L51-L87","documentation":"resolveExactSecurityOAuthAccess() got a resolution object from getOAuthAccessByCredentialId but with ok:false — the credential exists yet its access token could not be produced (typically a failed refresh). The function narrows the union and throws so callers only ever receive a valid access resolution.","triggerScenarios":"The stored refresh token is expired/revoked so AuthStorage cannot mint a new access token (even with forceRefresh), or the provider rejects the refresh request during getOAuthAccessByCredentialId.","commonSituations":"Long-idle credentials whose refresh token expired; provider-side session revocation (password change, sign-out-everywhere); clock skew invalidating tokens.","solutions":["Re-run authentication for the provider to store fresh tokens","Delete the broken credential and log in again","Check provider token endpoint health/network if refresh fails transiently","Retry with forceRefresh: true to force a token refresh attempt"],"exampleFix":"// before\nconst access = await resolveExactSecurityOAuthAccess(storage, account, { forceRefresh: false });\n// after\ntry {\n  const access = await resolveExactSecurityOAuthAccess(storage, account, { forceRefresh: true });\n} catch {\n  await reauthenticate(provider); // refresh token dead; re-login\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  const access = await resolveExactSecurityOAuthAccess(storage, account, { forceRefresh: true });\n} catch (err) {\n  if (err.message.includes(\"could not be resolved\")) {\n    // refresh token dead: trigger interactive re-auth, then retry once\n    await reauthenticate(account.provider);\n  } else throw err;\n}","preventionTips":["Refresh tokens proactively before expiry","Detect ok:false resolutions early and re-authenticate","Monitor for repeated refresh failures as a signal to re-login"],"tags":["oauth","token-refresh","authentication"],"backgroundTag":"token-refresh-failed","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}