can1357/oh-my-pi · error · SearchProviderError
Refusing to send official xAI OAuth credentials to custom en
Error message
Refusing to send official xAI OAuth credentials to custom endpoint ${transport.baseURL}. Configure an API key for provider "xai-oauth". What it means
searchXAI refuses to send official xAI OAuth credentials (from OAuth login or environment) to a non-default/custom endpoint. Because OAuth tokens grant broad account access, silently forwarding them to an arbitrary baseURL would be a credential-leak risk. The library throws this SearchProviderError and demands an explicit API key for provider "xai-oauth" instead.
Source
Thrown at packages/coding-agent/src/web/search/providers/xai.ts:410
return xaiResolver(ctx);
};
return { provider: "xai-oauth", keyOrResolver };
}
/** Execute xAI Responses API web search. */
export async function searchXAI(params: SearchParams): Promise<SearchResponse> {
const auth = resolveXAIWebSearchAuth(params);
const transport = params.modelRegistry
? resolveXAIHttpTransport(params.modelRegistry, auth.provider, XAI_WEB_SEARCH_MODEL)
: { baseURL: XAI_DEFAULT_BASE_URL };
const customEndpoint = transport.baseURL.replace(/\/+$/, "") !== XAI_DEFAULT_BASE_URL;
const credentialOrigin = params.authStorage.getCredentialOrigin(auth.provider);
if (
customEndpoint &&
auth.provider === "xai-oauth" &&
(credentialOrigin?.kind === "oauth" || credentialOrigin?.kind === "env")
) {
throw new SearchProviderError(
"xai",
`Refusing to send official xAI OAuth credentials to custom endpoint ${transport.baseURL}. Configure an API key for provider "xai-oauth".`,
);
}
const keyOrResolver: ApiKey = customEndpoint
? params.authStorage.resolver(auth.provider, { sessionId: params.sessionId })
: auth.keyOrResolver;
const resultCap = clampNumResults(params.numSearchResults ?? params.limit, DEFAULT_NUM_RESULTS, MAX_NUM_RESULTS);
const response = await withAuth(keyOrResolver, (key: string) => callXAIResponses(key, params, transport), {
signal: params.signal,
missingKeyMessage: 'xAI credentials not found. Set XAI_API_KEY or configure an API key for provider "xai".',
});
const parsed = parseResponse(response, resultCap);
if (!parsed.answer && parsed.sources.length === 0) {
throw new SearchProviderError("xai", "xAI web_search returned no answer or sources", 502);
}
return parsed;View on GitHub (pinned to 9690622007)
Solutions
- Configure a plain API key for provider "xai-oauth" (or provider "xai") so the OAuth credential is not used against the custom endpoint
- Remove the custom baseURL override so requests go to the official xAI endpoint, where OAuth is allowed
- Unset XAI_OAUTH_TOKEN and log out of xAI OAuth if you intend to use only an API key with the custom endpoint
- Store the API key explicitly in auth storage for the xai provider so resolveXAIWebSearchAuth picks provider "xai" instead of "xai-oauth"
Example fix
// before: OAuth creds + custom endpoint -> throws // (XAI_OAUTH_TOKEN set, baseURL = https://my-proxy.example.com/v1) // after: use an API key for the custom endpoint process.env.XAI_OAUTH_TOKEN = ""; // remove OAuth token process.env.XAI_API_KEY = "xai-xxxxxxxx"; // or store via auth storage for provider "xai"
Defensive patterns
Strategy: validation
Validate before calling
const usingOAuth = Boolean(process.env.XAI_OAUTH_TOKEN) || authOrigin?.kind === "oauth";
const customEndpoint = baseURL !== officialXAIBaseURL;
if (usingOAuth && customEndpoint) {
// fix config before calling:
// unset XAI_OAUTH_TOKEN and set XAI_API_KEY, or remove the custom baseURL
throw new Error("Refusing OAuth token to custom endpoint; configure an API key");
} Type guard
const isCredentialLeakGuard = (e: unknown): e is SearchProviderError =>
e instanceof SearchProviderError && e.message.includes("Refusing to send official xAI OAuth credentials"); Try / catch
try {
result = await searchXAI(params);
} catch (err) {
if (isCredentialLeakGuard(err)) {
// reconfigure: store an API key for provider "xai" or "xai-oauth", then retry once
return searchXAI({ ...params /* with API-key auth */ });
}
throw err;
} Prevention
- Never pair XAI_OAUTH_TOKEN/OAuth login with a custom baseURL in the same environment
- Store an explicit API key in auth storage for the xai provider when using custom endpoints
- Audit environment setup in CI: assert XAI_OAUTH_TOKEN is unset when a gateway baseURL is configured
- Prefer provider "xai" (API key) for any proxy or OpenAI-compat gateway
When it happens
Trigger: All of: (1) transport.baseURL differs from XAI_DEFAULT_BASE_URL (custom endpoint configured via modelRegistry/transport), (2) selected auth provider is "xai-oauth", and (3) credentialOrigin.kind is "oauth" or "env" (i.e. the credential came from OAuth login or XAI_OAUTH_TOKEN, not an explicitly stored API key).
Common situations: User logged in via `omp` xAI OAuth but also configured a custom/compat endpoint (e.g. an OpenAI-compatible proxy) in the model registry; CI sets XAI_OAUTH_TOKEN while a gateway baseURL is configured; switched the provider endpoint to a regional mirror without swapping to an API key.
Related errors
- xAI device-code response was not a JSON object.
- xAI device-code response missing or invalid required fields.
- ${label} was not a JSON object
- ${label} missing access_token
- ${label} missing refresh_token
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/e163b61211899c6c.
Report an issue: GitHub.