can1357/oh-my-pi · error · SearchProviderError

Kimi search API error (${response.status}): ${errorText}

Error message

Kimi search API error (${response.status}): ${errorText}

What it means

Thrown by callKimiSearch when the Kimi search API responds with a non-OK HTTP status that classifyProviderHttpError does not classify. The error message embeds both the HTTP status and the raw response body text for diagnosis, with the status attached to the SearchProviderError.

Source

Thrown at packages/coding-agent/src/web/search/providers/kimi.ts:134

		headers: {
			Accept: "application/json",
			"Content-Type": "application/json",
			Authorization: `Bearer ${apiKey}`,
		},
		body: JSON.stringify({
			text_query: params.query,
			limit: params.limit,
			enable_page_crawling: params.includeContent,
			timeout_seconds: DEFAULT_TIMEOUT_SECONDS,
		}),
		signal: withHardTimeout(params.signal, params.timeoutMs),
	});

	if (!response.ok) {
		const errorText = await response.text();
		const classified = classifyProviderHttpError("kimi", response.status, errorText);
		if (classified) throw classified;
		throw new SearchProviderError(
			"kimi",
			`Kimi search API error (${response.status}): ${errorText}`,
			response.status,
		);
	}

	const data = (await response.json()) as KimiSearchResponse;
	const requestId = response.headers.get("x-request-id") ?? response.headers.get("x-msh-request-id") ?? undefined;
	return { response: data, requestId };
}

/** Execute Kimi web search. */
export async function searchKimi(params: KimiSearchParams): Promise<SearchResponse> {
	const keyOrResolver = await resolveKey(params.authStorage, params.sessionId, params.signal);
	if (!keyOrResolver) {
		throw new Error(
			"Kimi search credentials not found. Kimi web search uses the Kimi Code service (api.kimi.com); set MOONSHOT_SEARCH_API_KEY / KIMI_SEARCH_API_KEY to a Kimi Code Console key, or login with 'omp /login kimi-code'. A Moonshot Open Platform key (MOONSHOT_API_KEY) is not accepted here.",
		);

View on GitHub (pinned to 9690622007)

Solutions

  1. Inspect errorText in the message — it contains Kimi's own error description
  2. Retry with backoff for 5xx statuses; treat 4xx as non-retryable
  3. Verify the API key and endpoint (Kimi Code console key, not Moonshot platform key)
  4. Check Kimi service status for outages

Example fix

// before
const results = await searchKimi({ query, authStorage });
// after
try {
  const results = await searchKimi({ query, authStorage });
} catch (err) {
  if (err instanceof SearchProviderError && (err.status ?? 500) >= 500) {
    await Bun.sleep(retryDelay); // retry transient 5xx
  }
}
Defensive patterns

Strategy: retry

Validate before calling

// preflight credential check against Kimi Code service
if (!process.env.MOONSHOT_SEARCH_API_KEY && !process.env.KIMI_SEARCH_API_KEY) {
  throw new Error('Kimi search key missing');
}

Try / catch

try {
  const res = await searchKimi({ query, authStorage });
} catch (err) {
  if (err instanceof SearchProviderError && (err.status ?? 0) >= 500) {
    await Bun.sleep(1000); return searchKimi({ query, authStorage }); // bounded retry
  }
  throw err;
}

Prevention

When it happens

Trigger: Any searchKimi call where the Kimi (api.kimi.com) endpoint returns status outside the classified set — e.g. 402, 409, 502/504 variants — with the body captured in errorText.

Common situations: Kimi service incidents returning 5xx with HTML error pages; rate-limit variants not covered by classification; transient gateway errors between client and Kimi.

Related errors


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