can1357/oh-my-pi · error
The pinned security OAuth credential could not be resolved
Error message
The pinned security OAuth credential could not be resolved
What it means
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.
Source
Thrown at packages/coding-agent/src/security/auth.ts:69
);
}
const account: SecurityAccountRef = { provider, credentialId: selected.credentialId };
if (selected.accountId !== undefined) account.accountId = selected.accountId;
if (selected.email !== undefined) account.email = selected.email;
if (selected.orgId !== undefined) account.organizationId = selected.orgId;
if (selected.orgName !== undefined) account.organizationName = selected.orgName;
return account;
}
export async function resolveExactSecurityOAuthAccess(
authStorage: AuthStorage,
account: SecurityAccountRef,
options: { forceRefresh: boolean; signal?: AbortSignal },
): Promise<Extract<OAuthAccessResolution, { ok: true }>> {
const resolution = await authStorage.getOAuthAccessByCredentialId(account.provider, account.credentialId, options);
if (!resolution) throw new Error("The pinned security OAuth credential is unavailable");
assertSecurityIdentityMatches(account, resolution);
if (!resolution.ok) throw new Error("The pinned security OAuth credential could not be resolved");
return resolution;
}
/**
* Build a request credential resolver pinned to one durable OAuth row.
*
* Initial resolution and refresh both target the same row. The auth driver's
* final sibling-rotation step returns `undefined`, so an unavailable account
* fails the scan rather than crossing an account/workspace boundary.
*/
export function createExactSecurityOAuthResolver(
options: ExactSecurityOAuthOptions,
): NonNullable<AgentOptions["getApiKey"]> {
const { account, authStorage } = options;
return model => {
if (model.provider !== account.provider) {
throw new Error("Security scan authentication provider mismatch");
}View on GitHub (pinned to 9690622007)
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
Example fix
// before
const access = await resolveExactSecurityOAuthAccess(storage, account, { forceRefresh: false });
// after
try {
const access = await resolveExactSecurityOAuthAccess(storage, account, { forceRefresh: true });
} catch {
await reauthenticate(provider); // refresh token dead; re-login
} Defensive patterns
Strategy: try-catch
Try / catch
try {
const access = await resolveExactSecurityOAuthAccess(storage, account, { forceRefresh: true });
} catch (err) {
if (err.message.includes("could not be resolved")) {
// refresh token dead: trigger interactive re-auth, then retry once
await reauthenticate(account.provider);
} else throw err;
} Prevention
- Refresh tokens proactively before expiry
- Detect ok:false resolutions early and re-authenticate
- Monitor for repeated refresh failures as a signal to re-login
When it happens
Trigger: 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.
Common situations: Long-idle credentials whose refresh token expired; provider-side session revocation (password change, sign-out-everywhere); clock skew invalidating tokens.
Related errors
- Codex OAuth credential is missing a ChatGPT account id
- OAuth refresh did not produce a usable credential for provid
- OAuth provider "${provider}" does not support token refresh
- Antigravity credentials missing projectId
- Google Cloud credentials missing projectId
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/415254065516ade0.
Report an issue: GitHub.