musistudio/claude-code-router · warning

[gateway] Google CSE web search API key or engine ID is not

Error message

[gateway] Google CSE web search API key or engine ID is not configured.

What it means

The Google Custom Search Engine provider requires both an API key (GOOGLE_SEARCH_API_KEY) and an engine ID (GOOGLE_SEARCH_CX). Either or both are missing from the resolved environment, so the provider returns no results.

Source

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

    return [];
  }
  const url = new URL(searchEnv(input, "BING_SEARCH_ENDPOINT") || "https://api.bing.microsoft.com/v7.0/search");
  url.searchParams.set("q", input.query);
  url.searchParams.set("count", String(input.count));
  url.searchParams.set("mkt", "en-US");
  const raw = await fetchJson(url.toString(), {
    headers: { "ocp-apim-subscription-key": apiKey },
    signal: AbortSignal.timeout(input.timeoutMs)
  });
  const items = isRecord(raw) && isRecord(raw.webPages) && Array.isArray(raw.webPages.value) ? raw.webPages.value : [];
  return items.map((item) => webSearchResult(item, "name", "url", "snippet")).filter(isWebSearchProviderResult);
}

async function searchGoogleCse(input: WebSearchProviderInput): Promise<WebSearchProviderResult[]> {
  const apiKey = searchEnv(input, "GOOGLE_SEARCH_API_KEY");
  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 [];
  }

View on GitHub (pinned to 99f24806c6)

Solutions

  1. Create a Programmable Search Engine at programmablesearchengine.google.com and copy its cx ID
  2. Set both GOOGLE_SEARCH_API_KEY and GOOGLE_SEARCH_CX in the gateway environment
  3. Enable the Custom Search API on the key's GCP project and restart the gateway

Example fix

# before
GOOGLE_SEARCH_API_KEY=AIza...

# after
GOOGLE_SEARCH_API_KEY=AIza...
GOOGLE_SEARCH_CX=0123456789abcdef:xyz
WEB_SEARCH_PROVIDER=google
Defensive patterns

Strategy: validation

Validate before calling

const missing = ["GOOGLE_SEARCH_API_KEY", "GOOGLE_SEARCH_CX"].filter((k) => !process.env[k]);
if (missing.length) throw new Error(`Google CSE requires: ${missing.join(", ")}`);

Prevention

When it happens

Trigger: Configuring web search provider to "google" while only setting GOOGLE_SEARCH_API_KEY and not GOOGLE_SEARCH_CX (or vice versa); misspelling either variable; the CSE not being created in the Google Cloud console so the cx value was never obtained.

Common situations: Devs obtain an API key but forget they must also create a Custom Search Engine and copy its cx ID; env vars set in a different environment; using the Google Search API (deprecated) variable names instead of CSE ones.

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/87fbcbddea828fd2. Report an issue: GitHub.