{"record":{"id":"a68e8d69a778792c","repo":"Mintplex-Labs/anything-llm","slug":"res-status-res-statustext-params-json","errorCode":null,"errorMessage":"${res.status} - ${res.statusText}. params: ${JSON.stringify({ auth: this.middleTruncate(process.env.AGENT_SERPAPI_API_KEY, 5), q: query })}","messagePattern":"(.+?) - (.+?)\\. params: (.+?)\\)\\}","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/utils/agents/aibitat/plugins/web-browsing.js","lineNumber":202,"sourceCode":"            );\n\n            const engine = process.env.AGENT_SERPAPI_ENGINE;\n            const queryParamKey = engine === \"amazon\" ? \"k\" : \"q\";\n\n            const params = new URLSearchParams({\n              engine: engine,\n              [queryParamKey]: query,\n              api_key: process.env.AGENT_SERPAPI_API_KEY,\n            });\n\n            const url = `https://serpapi.com/search.json?${params.toString()}`;\n            const { response, error } = await fetch(url, {\n              method: \"GET\",\n              headers: {},\n            })\n              .then((res) => {\n                if (res.ok) return res.json();\n                throw new Error(\n                  `${res.status} - ${res.statusText}. params: ${JSON.stringify({ auth: this.middleTruncate(process.env.AGENT_SERPAPI_API_KEY, 5), q: query })}`\n                );\n              })\n              .then((data) => {\n                return { response: data, error: null };\n              })\n              .catch((e) => {\n                this.super.handlerProps.log(`SerpApi Error: ${e.message}`);\n                return { response: null, error: e.message };\n              });\n            if (error)\n              return `There was an error searching for content. ${error}`;\n\n            const data = [];\n\n            switch (engine) {\n              case \"google\":\n                if (response.hasOwnProperty(\"knowledge_graph\"))","sourceCodeStart":184,"sourceCodeEnd":220,"githubUrl":"https://github.com/Mintplex-Labs/anything-llm/blob/a145d4d87d086bdb31d50f9bf9cd9c46d311780c/server/utils/agents/aibitat/plugins/web-browsing.js#L184-L220","documentation":"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>'.","triggerScenarios":"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).","commonSituations":"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).","solutions":["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.","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.","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'."],"exampleFix":"# before\n# .env has a SearchApi key under the SerpApi variable\nAGENT_SERPAPI_API_KEY=searchapi-xxxx  # 401 - Unauthorized\n\n# after\nAGENT_SERPAPI_API_KEY=<real serpapi.com key>\n# then restart the server","handlingStrategy":"validation","validationCode":"function assertSearchProviderConfigured(provider) {\n  const keyMap = { serpapi: \"AGENT_SERPAPI_API_KEY\", searchapi: \"AGENT_SEARCHAPI_API_KEY\", serper: \"AGENT_SERPER_DEV_KEY\", baidu: \"AGENT_BAIDU_SEARCH_API_KEY\" };\n  const key = process.env[keyMap[provider]];\n  if (!key) throw new Error(`${keyMap[provider]} is not set — configure it in server .env and restart`);\n  return key;\n}","typeGuard":null,"tryCatchPattern":"// plugin already converts the throw into a string; inspect it at the caller:\nconst out = await webSearch(query);\nif (typeof out === \"string\" && out.startsWith(\"There was an error searching for content.\")) {\n  if (out.includes(\"401\")) fixApiKey(\"AGENT_SERPAPI_API_KEY\");\n  else if (out.includes(\"429\")) backoffAndRetryLater(); // quota/rate limit\n  else logProviderIssue(out);\n}","preventionTips":["Set only the env key for the provider you use; unset the others so the agent cannot select them.","Restart the server after .env changes — process.env is read at request time but keys are often set once.","Watch quotas on the SerpApi dashboard and alert before exhaustion (429).","Do not re-log the full error message: it contains a 5-char middle-truncated key — keep truncation intact."],"tags":["web-search","serpapi","http-error","api-key","agent-tools"],"backgroundTag":"search-api-http-error","analyzedSha":"a145d4d87d086bdb31d50f9bf9cd9c46d311780c","analyzedAt":"2026-08-18T10:02:21.017Z","contentChangedAt":"2026-08-18T10:02:21.017Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}