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
- Verify AGENT_SERPER_DEV_KEY is set in the environment and matches an active key from serper.dev.
- A 402 specifically means credits are depleted — top up or switch plans on the Serper dashboard.
- A 401 means the key is wrong or unset — check the truncated value in the error.
- 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
- Confirm AGENT_SERPER_DEV_KEY is set before enabling Serper.dev search.
- Monitor credit balance (free tier is 2,500 searches).
- Handle 402 as a billing/credits issue distinct from 401 auth failures.
- Use the redirect: 'follow' option carefully — verify the final URL is the Serper endpoint.
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
- ${res.status} - ${res.statusText}. params: ${JSON.stringify(
- ${res.status} - ${res.statusText}. params: ${JSON.stringify(
- ${res.status} - ${res.statusText}. params: ${JSON.stringify(
- ${res.status} - ${res.statusText}. params: ${JSON.stringify(
- ${res.status} - ${res.statusText}. params: ${JSON.stringify(
AI-assisted analysis of Mintplex-Labs/anything-llm@526360e320 (2026-08-13).
Data as JSON: /api/errors/c36b5bf3af6a85d8.
Report an issue: GitHub.