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

  1. Configure a plain API key for provider "xai-oauth" (or provider "xai") so the OAuth credential is not used against the custom endpoint
  2. Remove the custom baseURL override so requests go to the official xAI endpoint, where OAuth is allowed
  3. Unset XAI_OAUTH_TOKEN and log out of xAI OAuth if you intend to use only an API key with the custom endpoint
  4. 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

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


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/e163b61211899c6c. Report an issue: GitHub.