can1357/oh-my-pi · error
The pinned security OAuth credential is unavailable
Error message
The pinned security OAuth credential is unavailable
What it means
resolveExactSecurityOAuthAccess() looks up the pinned credential row via authStorage.getOAuthAccessByCredentialId; when the lookup returns nothing (credential record no longer exists / not visible), it throws this error. It means the SecurityAccountRef points at a credential that is not present at resolution time.
Source
Thrown at packages/coding-agent/src/security/auth.ts:67
throw new Error(
`Multiple OAuth accounts are available for ${provider}; supply credentialId to pin one exact account`,
);
}
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) {View on GitHub (pinned to 9690622007)
Solutions
- Re-list stored OAuth credentials and re-pin a valid credentialId
- Re-authenticate with the provider to recreate the credential
- Remove the stale pinned credentialId and let account selection pick a current one
Example fix
// before
resolveExactSecurityOAuthAccess(authStorage, { provider: "openai-codex", credentialId: "old-id" }, opts)
// after
const accounts = listAccounts(authStorage, "openai-codex");
resolveExactSecurityOAuthAccess(authStorage, { provider: "openai-codex", credentialId: accounts[0].credentialId }, opts) Defensive patterns
Strategy: validation
Validate before calling
const stored = authStorage.listOAuthAccounts(account.provider);
if (!stored.some(a => a.credentialId === account.credentialId)) {
throw new Error(`Credential ${account.credentialId} no longer stored for ${account.provider}`);
} Try / catch
try {
const access = await resolveExactSecurityOAuthAccess(storage, account, opts);
} catch (err) {
if (err.message === "The pinned security OAuth credential is unavailable") {
await reauthenticate(account.provider); // re-pin fresh credential
} else throw err;
} Prevention
- Re-resolve the pinned credentialId at session start instead of persisting it long-term
- Re-pin after any logout/re-auth
- Verify credential existence before long-running scans
When it happens
Trigger: Calling resolveExactSecurityOAuthAccess (or any flow using createExactSecurityOAuthResolver) with a SecurityAccountRef whose credentialId no longer exists in AuthStorage for that provider — e.g. the credential was deleted, logged out, or rotated to a new id between pinning and use.
Common situations: Stale credentialId captured earlier in a long-lived config after the user re-authenticated; logout wiped the credential store; running on a machine whose AuthStorage never had that credential.
Related errors
- No OAuth accounts resolved for provider ${model.provider}
- OAuth authentication failed: ${errorMsg}
- Multiple OAuth accounts are available for ${provider}; suppl
- The pinned security OAuth credential could not be resolved
- No Codex OAuth credentials found. Login with 'omp /login ope
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/7410f38171a94946.
Report an issue: GitHub.