Mintplex-Labs/anything-llm · error

- . params: )}

Error message

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

What it means

Thrown inside the SerpApi branch of the web-browsing plugin when fetch to https://serpapi.com/search.json returns a non-ok response. The message concatenates HTTP status, statusText, the query, and the AGENT_SERPAPI_API_KEY middle-truncated to 5 characters. The surrounding .catch logs 'SerpApi Error' and converts the failure into an error string returned to the agent, so the throw rarely escapes the plugin — it surfaces as 'There was an error searching for content. <msg>'.

Solutions

  1. Verify AGENT_SERPAPI_API_KEY is set and correct for serpapi.com (not a SearchApi or Serper.dev key), then restart the server so the env var is loaded.
  2. Read the status in the returned message: 401 -> bad key; 429 -> quota/rate limit, check the SerpApi dashboard and upgrade/back off; 400 -> check the engine parameter.
  3. Confirm billing/plan status on the SerpApi dashboard and test the key directly: curl 'https://serpapi.com/search.json?engine=google&q=test&api_key=KEY'.

Example fix

# before
# .env has a SearchApi key under the SerpApi variable
AGENT_SERPAPI_API_KEY=searchapi-xxxx  # 401 - Unauthorized

# after
AGENT_SERPAPI_API_KEY=<real serpapi.com key>
# then restart the server
Defensive patterns

Strategy: validation

Validate before calling

function assertSearchProviderConfigured(provider) {
  const keyMap = { serpapi: "AGENT_SERPAPI_API_KEY", searchapi: "AGENT_SEARCHAPI_API_KEY", serper: "AGENT_SERPER_DEV_KEY", baidu: "AGENT_BAIDU_SEARCH_API_KEY" };
  const key = process.env[keyMap[provider]];
  if (!key) throw new Error(`${keyMap[provider]} is not set — configure it in server .env and restart`);
  return key;
}

Try / catch

// plugin already converts the throw into a string; inspect it at the caller:
const out = await webSearch(query);
if (typeof out === "string" && out.startsWith("There was an error searching for content.")) {
  if (out.includes("401")) fixApiKey("AGENT_SERPAPI_API_KEY");
  else if (out.includes("429")) backoffAndRetryLater(); // quota/rate limit
  else logProviderIssue(out);
}

Prevention

When it happens

Trigger: AGENT_SERPAPI_API_KEY missing/invalid/revoked (401 Unauthorized); plan quota or rate limit exhausted (429); invalid engine or query parameter (400); outage on serpapi.com (5xx).

Common situations: Key set in .env but server not restarted so process.env is stale; free-tier 100-searches-per-month exhausted mid-session; key rotated on the provider side; wrong provider key (SearchApi/Serper key used for SerpApi).

Related errors


AI-assisted analysis of Mintplex-Labs/anything-llm@a145d4d87d (2026-08-18). Data as JSON: /api/errors/a68e8d69a778792c. Report an issue: GitHub.

Appendix: source

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

            );

            const engine = process.env.AGENT_SERPAPI_ENGINE;
            const queryParamKey = engine === "amazon" ? "k" : "q";

            const params = new URLSearchParams({
              engine: engine,
              [queryParamKey]: query,
              api_key: process.env.AGENT_SERPAPI_API_KEY,
            });

            const url = `https://serpapi.com/search.json?${params.toString()}`;
            const { response, error } = await fetch(url, {
              method: "GET",
              headers: {},
            })
              .then((res) => {
                if (res.ok) return res.json();
                throw new Error(
                  `${res.status} - ${res.statusText}. params: ${JSON.stringify({ auth: this.middleTruncate(process.env.AGENT_SERPAPI_API_KEY, 5), q: query })}`
                );
              })
              .then((data) => {
                return { response: data, error: null };
              })
              .catch((e) => {
                this.super.handlerProps.log(`SerpApi Error: ${e.message}`);
                return { response: null, error: e.message };
              });
            if (error)
              return `There was an error searching for content. ${error}`;

            const data = [];

            switch (engine) {
              case "google":
                if (response.hasOwnProperty("knowledge_graph"))

View on GitHub (pinned to a145d4d87d)