can1357/oh-my-pi · critical · SearchProviderError
Refusing to send official Codex OAuth credentials to custom
Error message
Refusing to send official Codex OAuth credentials to custom endpoint ${transport.baseUrl}. Configure an API key for provider "openai-codex". What it means
When a custom Codex endpoint is configured, sending official OpenAI Codex OAuth credentials (ChatGPT-account tokens) to a third-party URL would leak privileged credentials, so searchCodex throws a SearchProviderError unless an API key for provider "openai-codex" (or a command-backed key) is available. Command-backed keys take priority over AuthStorage origins, so they bypass this refusal.
Source
Thrown at packages/coding-agent/src/web/search/providers/codex.ts:763
// request shape (responses-lite moves tools into an `additional_tools`
// developer item), so the documented `web_search.filters.allowed_domains`
// parameter cannot be assumed to survive it. Instead, re-emit directive
// queries with the full Google-style operator syntax — the backing index
// parses the classic operator set — and leave directive-free queries
// byte-identical.
const parsed = params.parsedQuery ?? parseSearchQuery(params.query);
const query = parsed.hasDirectives ? formatQuery(parsed, GOOGLE_QUERY_SYNTAX) : params.query;
let result: CodexSearchResult;
if (transport.customEndpoint) {
// ModelRegistry resolves command-backed provider keys before consulting
// its AuthStorage, so a lower-priority OAuth origin is irrelevant when
// that command source is configured.
const credentialSource = params.modelRegistry?.authStorage ?? params.authStorage;
const credentialOrigin = credentialSource.getCredentialOrigin("openai-codex");
const hasCommandBackedKey = params.modelRegistry?.hasCommandBackedApiKey("openai-codex") === true;
if (!hasCommandBackedKey && (credentialOrigin?.kind === "oauth" || credentialOrigin?.kind === "env")) {
throw new SearchProviderError(
"codex",
`Refusing to send official Codex OAuth credentials to custom endpoint ${transport.baseUrl}. Configure an API key for provider "openai-codex".`,
);
}
const resolverOptions = {
sessionId: params.sessionId,
baseUrl: transport.baseUrl,
modelId: firstCandidate.modelId,
};
const keyOrResolver = params.modelRegistry
? params.modelRegistry.resolver("openai-codex", resolverOptions)
: params.authStorage.resolver("openai-codex", resolverOptions);
result = await withAuth(
keyOrResolver,
accessToken =>
runCodexSearchCandidates({
auth: { accessToken },View on GitHub (pinned to 9690622007)
Solutions
- Configure a dedicated API key for provider "openai-codex" for use with the custom endpoint.
- Set up a command-backed API key (hasCommandBackedApiKey) so the custom endpoint uses it instead of OAuth.
- Remove the custom endpoint override so the official endpoint is used with OAuth credentials.
- Ensure the credential origin is an API-key source rather than oauth/env if you intend to keep the custom endpoint.
Example fix
// before customEndpoint = "https://gateway.corp.internal/v1"; // uses ChatGPT OAuth token -> refused // after // configure an API key for the gateway: omp /login openai-codex --api-key sk-gateway-... // or unset the custom endpoint to use official endpoint with OAuth
Defensive patterns
Strategy: validation
Validate before calling
const origin = authStorage.getCredentialOrigin("openai-codex");
const usingCustomEndpoint = transport.customEndpoint;
if (usingCustomEndpoint && (origin?.kind === "oauth" || origin?.kind === "env")) {
throw new Error('Custom endpoint requires an API key for provider "openai-codex"');
} Type guard
function isOAuthToCustomEndpointRefusal(e: unknown): e is SearchProviderError {
return e instanceof SearchProviderError && e.message.startsWith("Refusing to send official Codex OAuth credentials");
} Try / catch
try {
return await searchCodex(params);
} catch (e) {
if (isOAuthToCustomEndpointRefusal(e)) {
// configure an API key, then retry once
await configureApiKey("openai-codex");
return searchCodex(params);
}
throw e;
} Prevention
- Always pair a custom endpoint with a dedicated API key, never ChatGPT OAuth tokens.
- Use command-backed API keys for gateway deployments so they take credential priority.
- Audit credential origins (getCredentialOrigin) in CI before enabling custom endpoints.
When it happens
Trigger: resolveCodexSearchTransport returns a custom endpoint (non-official baseUrl), the resolved credential origin for openai-codex is "oauth" or "env"-derived from OAuth storage, and modelRegistry.hasCommandBackedApiKey("openai-codex") is false.
Common situations: Pointing the Codex provider at a corporate proxy or OpenAI-compatible gateway while still logged in via `omp /login openai-codex`; environment credential resolution falling back to OAuth; migration from official login to a self-hosted endpoint without issuing an API key.
Related errors
- Antigravity credentials missing projectId
- Google Cloud credentials missing projectId
- No Codex OAuth credentials found. Login with 'omp /login ope
- Unknown OAuth provider: ${provider}
- OAuth provider "${provider}" does not support token refresh
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/71f5b8eaba2e1235.
Report an issue: GitHub.