musistudio/claude-code-router · warning

[gateway] Serper web search API key is not configured.

Error message

[gateway] Serper web search API key is not configured.

What it means

The Serper.dev web search provider was selected, but SERPER_API_KEY is not configured in the resolved environment. The provider returns an empty result list, so searches silently produce nothing.

Source

Thrown at packages/core/src/gateway/features/hosted-web-search/discovery.ts:593

  const cx = searchEnv(input, "GOOGLE_SEARCH_CX");
  if (!apiKey || !cx) {
    console.warn("[gateway] Google CSE web search API key or engine ID is not configured.");
    return [];
  }
  const url = new URL(searchEnv(input, "GOOGLE_SEARCH_ENDPOINT") || "https://www.googleapis.com/customsearch/v1");
  url.searchParams.set("key", apiKey);
  url.searchParams.set("cx", cx);
  url.searchParams.set("q", input.query);
  url.searchParams.set("num", String(Math.min(input.count, 10)));
  const raw = await fetchJson(url.toString(), { signal: AbortSignal.timeout(input.timeoutMs) });
  const items = isRecord(raw) && Array.isArray(raw.items) ? raw.items : [];
  return items.map((item) => webSearchResult(item, "title", "link", "snippet")).filter(isWebSearchProviderResult);
}

async function searchSerper(input: WebSearchProviderInput): Promise<WebSearchProviderResult[]> {
  const apiKey = searchEnv(input, "SERPER_API_KEY");
  if (!apiKey) {
    console.warn("[gateway] Serper web search API key is not configured.");
    return [];
  }
  const raw = await fetchJson(searchEnv(input, "SERPER_SEARCH_ENDPOINT") || "https://google.serper.dev/search", {
    body: JSON.stringify({ num: input.count, q: input.query }),
    headers: {
      "content-type": "application/json",
      "x-api-key": apiKey
    },
    method: "POST",
    signal: AbortSignal.timeout(input.timeoutMs)
  });
  const items = isRecord(raw) && Array.isArray(raw.organic) ? raw.organic : [];
  return items.map((item) => webSearchResult(item, "title", "link", "snippet")).filter(isWebSearchProviderResult);
}

async function searchSerpApi(input: WebSearchProviderInput): Promise<WebSearchProviderResult[]> {
  const apiKey = searchEnv(input, "SERPAPI_API_KEY");
  if (!apiKey) {

View on GitHub (pinned to 99f24806c6)

Solutions

  1. Set SERPER_API_KEY to your serper.dev API key in the gateway environment
  2. Confirm the variable reaches the process (check service definition or container env)
  3. Restart the gateway

Example fix

# before
WEB_SEARCH_PROVIDER=serper

# after
SERPER_API_KEY=<serper-key>
WEB_SEARCH_PROVIDER=serper
Defensive patterns

Strategy: validation

Validate before calling

if (!process.env.SERPER_API_KEY) throw new Error("SERPER_API_KEY required for serper provider");

Prevention

When it happens

Trigger: Setting web search provider to "serper" without SERPER_API_KEY; the key not being propagated to the gateway's runtime environment (container, systemd, CI).

Common situations: Key obtained from serper.dev but stored in a shell rc file not sourced by the service; env var named differently (SERPER_KEY); stale deployment secrets.

Understand the failure class

Background: "environment variable is not set" and "Missing keys in environment" errors: what missing required env var messages mean and how to fix them — this error's family across 28 libraries.

Related errors


AI-assisted analysis of musistudio/claude-code-router@99f24806c6 (2026-08-27). Data as JSON: /api/errors/d54484229cf08300. Report an issue: GitHub.