can1357/oh-my-pi · error
Security scan authentication provider mismatch
Error message
Security scan authentication provider mismatch
What it means
createExactSecurityOAuthResolver() returns a getApiKey hook that throws immediately if the requested model's provider does not match the pinned SecurityAccountRef provider. It guarantees the security scan never uses credentials for one provider to authenticate requests against another.
Source
Thrown at packages/coding-agent/src/security/auth.ts:86
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");
}
const resolver: ApiKeyResolver = async context => {
if (context.lastChance) return undefined;
const resolution = await resolveExactSecurityOAuthAccess(authStorage, account, {
forceRefresh: context.error !== undefined,
signal: context.signal,
});
return resolution.accessToken;
};
return resolver;
};
}
View on GitHub (pinned to 9690622007)
Solutions
- Make the scan session use a model whose provider matches account.provider
- Recreate the resolver with a SecurityAccountRef for the provider the model actually uses
- Fix the pinned account provider value (e.g. "openai-codex" vs "openai" mixups)
Example fix
// before
createExactSecurityOAuthResolver({ account: { provider: "openai-codex", credentialId }, authStorage })
// used with an anthropic model -> mismatch
// after
createExactSecurityOAuthResolver({ account: { provider: model.provider, credentialId }, authStorage }) Defensive patterns
Strategy: validation
Validate before calling
if (model.provider !== account.provider) {
throw new Error(`Scan requires a ${account.provider} model, got ${model.provider}`);
} Type guard
const matchesAccount = (model: { provider: string }, account: { provider: string }): boolean =>
model.provider === account.provider; Try / catch
try {
await runScan(session);
} catch (err) {
if (err.message === "Security scan authentication provider mismatch") {
// rebuild resolver/agent with a model matching account.provider
} else throw err;
} Prevention
- Pin the model together with the account so both share one provider
- Validate session default model provider against the pinned account at setup
- Avoid multi-provider model lists in security scans
When it happens
Trigger: An agent run configured with an exact security OAuth resolver for provider X encounters a model whose provider is Y (e.g. pinned an openai-codex account but the run selects an anthropic model), so the model=>... guard throws.
Common situations: Model misconfiguration in the scan session (wrong default model/provider); multi-provider model lists where a non-pinned provider model gets picked; copy-pasting a resolver config across providers.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Codex Security cloud requires an openai-codex ChatGPT OAuth
- Unknown OAuth provider: ${provider}
- OAuth provider "${provider}" does not support token refresh
- Alibaba Coding Plan
- QwenCloud Token Plan
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/b801a8de590a8eba.
Report an issue: GitHub.