can1357/oh-my-pi · error
Multiple OAuth accounts are available for ${provider}; suppl
Error message
Multiple OAuth accounts are available for ${provider}; supply credentialId to pin one exact account What it means
selectSecurityAccount() refuses to guess which stored OAuth account to use when a provider has more than one credential and none is marked active and no credentialId was supplied. The library requires an exact, unambiguous account reference before running security scans. This prevents scans from authenticating as the wrong identity.
Source
Thrown at packages/coding-agent/src/security/auth.ts:49
}
export function selectSecurityAccount(
authStorage: AuthStorage,
provider: string,
requestedCredentialId?: number,
sessionId?: string,
): SecurityAccountRef {
const accounts = authStorage.listOAuthAccounts(provider, sessionId);
const selected =
requestedCredentialId !== undefined
? accounts.find(account => account.credentialId === requestedCredentialId)
: (accounts.find(account => account.active) ?? (accounts.length === 1 ? accounts[0] : undefined));
if (!selected) {
if (accounts.length === 0) throw new Error(`Security scans require a stored OAuth account for ${provider}`);
if (requestedCredentialId !== undefined) {
throw new Error(`Security OAuth credential ${requestedCredentialId} is not available for ${provider}`);
}
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");View on GitHub (pinned to 9690622007)
Solutions
- Pass an explicit credentialId option to pin the account you want
- Mark one stored account as active in AuthStorage
- Remove stale/duplicate OAuth credentials for the provider so only one remains
- List stored credentials (auth storage contents) to find the correct credentialId
Example fix
// before const account = selectSecurityAccount(authStorage, provider, undefined); // after const account = selectSecurityAccount(authStorage, provider, "cred_abc123");
Defensive patterns
Strategy: validation
Validate before calling
const accounts = authStorage.listOAuthAccounts(provider);
if (accounts.length > 1 && !accounts.some(a => a.active) && !credentialId) {
throw new Error(`Pick one of ${accounts.length} ${provider} credentials: ${accounts.map(a => a.credentialId).join(", ")}`);
} Try / catch
try {
const account = selectSecurityAccount(authStorage, provider, credentialId);
} catch (err) {
if (err.message.includes("Multiple OAuth accounts")) {
// prompt user to choose / pass credentialId
} else throw err;
} Prevention
- Always pass an explicit credentialId in automated/headless runs
- Keep exactly one credential per provider
- Mark the intended default account as active
When it happens
Trigger: Calling security-scan flows (via selectSecurityAccount) for a provider that has 2+ stored OAuth credentials in AuthStorage, with no active flag set and no requestedCredentialId. Passing a credentialId only avoids this if it matches; otherwise the 'not available' variant throws instead.
Common situations: Developers who re-logged into the same provider (e.g. ChatGPT/openai-codex) twice, creating duplicate credentials; accounts synced from multiple machines; a previously-active credential lost its active flag after re-auth.
Related errors
- Unknown OAuth provider: ${provider}
- OAuth provider "${provider}" does not support token refresh
- Alibaba Coding Plan
- QwenCloud Token Plan
- Invalid QwenCloud Cookie header. Copy the complete Cookie re
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/cb9202f703e7deec.
Report an issue: GitHub.