Mintplex-Labs/anything-llm · error · Error

${res.status} - ${res.statusText}. params: ${JSON.stringify(

Error message

${res.status} - ${res.statusText}. params: ${JSON.stringify({ auth: this.middleTruncate(process.env.AGENT_SERPER_DEV_KEY, 5), q: query })}

What it means

Thrown by the Serper.dev provider when a POST to https://google.serper.dev/search returns a non-OK status. Authentication uses the AGENT_SERPER_DEV_KEY in the X-API-KEY header. The error message includes the status code, status text, a middle-truncated key, and the query. The .catch logs 'Serper.dev Error' and returns a failure string.

Source

Thrown at server/utils/agents/aibitat/plugins/web-browsing.js:527

              `${this.caller}: Using Serper.dev to search for "${
                query.length > 100 ? `${query.slice(0, 100)}...` : query
              }"`
            );
            const { response, error } = await fetch(
              "https://google.serper.dev/search",
              {
                method: "POST",
                headers: {
                  "X-API-KEY": process.env.AGENT_SERPER_DEV_KEY,
                  "Content-Type": "application/json",
                },
                body: JSON.stringify({ q: query }),
                redirect: "follow",
              }
            )
              .then((res) => {
                if (res.ok) return res.json();
                throw new Error(
                  `${res.status} - ${res.statusText}. params: ${JSON.stringify({ auth: this.middleTruncate(process.env.AGENT_SERPER_DEV_KEY, 5), q: query })}`
                );
              })
              .then((data) => {
                return { response: data, error: null };
              })
              .catch((e) => {
                this.super.handlerProps.log(`Serper.dev Error: ${e.message}`);
                return { response: null, error: e.message };
              });
            if (error)
              return `There was an error searching for content. ${error}`;

            const data = [];
            if (response.hasOwnProperty("knowledgeGraph"))
              data.push(response.knowledgeGraph);
            response.organic?.forEach((searchResult) => {
              const { title, link, snippet } = searchResult;

View on GitHub (pinned to 526360e320)

Solutions

  1. Verify AGENT_SERPER_DEV_KEY is set in the environment and matches an active key from serper.dev.
  2. A 402 specifically means credits are depleted — top up or switch plans on the Serper dashboard.
  3. A 401 means the key is wrong or unset — check the truncated value in the error.
  4. For 429, reduce the frequency of agent searches or implement backoff.

Example fix

// before
headers: { "X-API-KEY": process.env.AGENT_SERPER_DEV_KEY, ... },

// caller-side fix — validate before the request
if (!process.env.AGENT_SERPER_DEV_KEY) {
  return "AGENT_SERPER_DEV_KEY is not configured.";
}
Defensive patterns

Strategy: validation

Validate before calling

if (!process.env.AGENT_SERPER_DEV_KEY) {
  throw new Error("AGENT_SERPER_DEV_KEY is not set. Configure it to use Serper.dev.");
}

Try / catch

try {
  const results = await serperSearch(query);
  return results;
} catch (e) {
  if (e.message.includes("402")) {
    return "Serper.dev credits exhausted. Top up at serper.dev.";
  }
  if (e.message.startsWith("401")) {
    return "Serper.dev API key invalid. Check AGENT_SERPER_DEV_KEY.";
  }
  throw e;
}

Prevention

When it happens

Trigger: Serper.dev returns 401 (invalid X-API-KEY), 402 (free credits exhausted — Serper uses a credit system), 429 (rate limit), 400 (malformed body), or 5xx. An unset AGENT_SERPER_DEV_KEY sends an empty X-API-KEY header, always triggering 401.

Common situations: Free tier (2,500 credits) exhausted; key never configured; key revoked; redirect chain broken (redirect: 'follow' fails); concurrent searches exceeding the per-second rate limit.

Related errors


AI-assisted analysis of Mintplex-Labs/anything-llm@526360e320 (2026-08-13). Data as JSON: /api/errors/c36b5bf3af6a85d8. Report an issue: GitHub.