musistudio/claude-code-router · warning

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

Error message

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

What it means

The Tavily web search provider was selected, but TAVILY_API_KEY is not present in the resolved environment. The provider returns an empty result list, degrading search-augmented responses silently.

Source

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

  const apiKey = searchEnv(input, "SERPAPI_API_KEY");
  if (!apiKey) {
    console.warn("[gateway] SerpAPI web search API key is not configured.");
    return [];
  }
  const url = new URL(searchEnv(input, "SERPAPI_SEARCH_ENDPOINT") || "https://serpapi.com/search.json");
  url.searchParams.set("api_key", apiKey);
  url.searchParams.set("engine", "google");
  url.searchParams.set("q", input.query);
  url.searchParams.set("num", String(input.count));
  const raw = await fetchJson(url.toString(), { signal: AbortSignal.timeout(input.timeoutMs) });
  const items = isRecord(raw) && Array.isArray(raw.organic_results) ? raw.organic_results : [];
  return items.map((item) => webSearchResult(item, "title", "link", "snippet")).filter(isWebSearchProviderResult);
}

async function searchTavily(input: WebSearchProviderInput): Promise<WebSearchProviderResult[]> {
  const apiKey = searchEnv(input, "TAVILY_API_KEY");
  if (!apiKey) {
    console.warn("[gateway] Tavily web search API key is not configured.");
    return [];
  }
  const raw = await fetchJson(searchEnv(input, "TAVILY_SEARCH_ENDPOINT") || "https://api.tavily.com/search", {
    body: JSON.stringify({
      api_key: apiKey,
      max_results: input.count,
      query: input.query,
      search_depth: "basic"
    }),
    headers: { "content-type": "application/json" },
    method: "POST",
    signal: AbortSignal.timeout(input.timeoutMs)
  });
  const items = isRecord(raw) && Array.isArray(raw.results) ? raw.results : [];
  return items.map((item) => webSearchResult(item, "title", "url", "content")).filter(isWebSearchProviderResult);
}

async function searchExa(input: WebSearchProviderInput): Promise<WebSearchProviderResult[]> {

View on GitHub (pinned to 99f24806c6)

Solutions

  1. Set TAVILY_API_KEY in the gateway environment
  2. Confirm the gateway process can read it (logs or /proc/<pid>/environ)
  3. Restart the gateway

Example fix

# before
WEB_SEARCH_PROVIDER=tavily

# after
TAVILY_API_KEY=tvly-...
WEB_SEARCH_PROVIDER=tavily
Defensive patterns

Strategy: validation

Validate before calling

if (!process.env.TAVILY_API_KEY) throw new Error("TAVILY_API_KEY required for tavily provider");

Prevention

When it happens

Trigger: Setting web search provider to "tavily" without TAVILY_API_KEY; the key living only in a dev shell while the gateway runs as a daemon.

Common situations: Key from tavily.com not exported; .env file not copied into the deployment; env var naming mismatch.

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