{"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":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"server/utils/agents/aibitat/plugins/web-browsing.js","lineNumber":196,"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":178,"sourceCodeEnd":214,"githubUrl":"https://github.com/Mintplex-Labs/anything-llm/blob/526360e320da9d1b36074be5ed64fe76e5bbfbbd/server/utils/agents/aibitat/plugins/web-browsing.js#L178-L214","documentation":"Thrown inside the SerpApi search provider when fetch() to https://serpapi.com/search.json returns a non-OK HTTP status (anything outside 200–299). The error includes the status code, status text, a middle-truncated view of the API key, and the query. The .catch downstream logs the error and returns a user-facing string, so this error is caught but the search fails.","triggerScenarios":"SerpApi returns 401 (invalid/missing AGENT_SERPAPI_API_KEY), 429 (rate limit or quota exhausted), 402 (payment required — free tier exhausted), 400 (malformed query), or 5xx (SerpApi outage). The key may be unset, expired, or lack credits.","commonSituations":"API key was never set in environment; key was revoked or rotated; free-tier searches depleted; sudden burst of agent searches hitting the rate limit; SerpApi upstream incident; query contains characters SerpApi rejects.","solutions":["Verify AGENT_SERPAPI_API_KEY is set and valid in the environment (check server settings or .env).","Check the truncated key in the error matches what you expect — if it shows undefined, the env var is not set.","A 429 or 402 means you need to upgrade your SerpApi plan or wait for quota reset.","A 401 means the key is wrong — regenerate it from the SerpApi dashboard and update the setting.","Retry after a brief delay for transient 5xx errors."],"exampleFix":"// before\nif (res.ok) return res.json();\nthrow new Error(`${res.status} - ${res.statusText}. params: ${JSON.stringify({auth: ..., q: query})}`);\n\n// caller-side fix — check key before calling\nif (!process.env.AGENT_SERPAPI_API_KEY) {\n  return \"AGENT_SERPAPI_API_KEY is not configured. Set it in the server environment.\";\n}\n// proceed with fetch","handlingStrategy":"validation","validationCode":"if (!process.env.AGENT_SERPAPI_API_KEY) {\n  throw new Error(\"AGENT_SERPAPI_API_KEY is not set. Configure it to use SerpApi search.\");\n}\n// Optionally validate key format before the request","typeGuard":null,"tryCatchPattern":"try {\n  const results = await serpApiSearch(query);\n  return results;\n} catch (e) {\n  if (e.message.startsWith(\"4\") || e.message.includes(\"401\")) {\n    return \"SerpApi authentication or quota error. Check AGENT_SERPAPI_API_KEY and plan status.\";\n  }\n  // Retry once for 5xx\n  if (e.message.startsWith(\"5\")) {\n    return await serpApiSearch(query); // single retry\n  }\n  throw e;\n}","preventionTips":["Set and verify AGENT_SERPAPI_API_KEY before enabling the web-browsing agent skill.","Monitor SerpApi credit usage to catch quota exhaustion early.","Implement a key-presence check at agent startup, not just at call time.","Handle 429 with exponential backoff rather than immediate retries."],"tags":["serpapi","web-search","http","api-key","rate-limit","agent-tool"],"backgroundTag":null,"analyzedSha":"526360e320da9d1b36074be5ed64fe76e5bbfbbd","analyzedAt":"2026-08-13T01:45:47.170Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}