Mintplex-Labs/anything-llm · error · Error

Unauthorized. Please double check your AGENT_SERPLY_API_KEY

Error message

Unauthorized. Please double check your AGENT_SERPLY_API_KEY

What it means

Thrown by the Serly provider specifically when the HTTP response is 200 OK (so it passed the res.ok check) but the JSON body contains {message: 'Unauthorized'}. Serly uses this non-standard pattern instead of a proper 401 status. This is a second-layer auth check after the HTTP status check passes.

Source

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

            const { response, error } = await fetch(url, {
              method: "GET",
              headers: {
                "X-API-KEY": process.env.AGENT_SERPLY_API_KEY,
                "Content-Type": "application/json",
                "User-Agent": "anything-llm",
                "X-Proxy-Location": proxy_location,
                "X-User-Agent": device_type,
              },
            })
              .then((res) => {
                if (res.ok) return res.json();
                throw new Error(
                  `${res.status} - ${res.statusText}. params: ${JSON.stringify({ auth: this.middleTruncate(process.env.AGENT_SERPLY_API_KEY, 5), q: query })}`
                );
              })
              .then((data) => {
                if (data?.message === "Unauthorized")
                  throw new Error(
                    "Unauthorized. Please double check your AGENT_SERPLY_API_KEY"
                  );
                return { response: data, error: null };
              })
              .catch((e) => {
                this.super.handlerProps.log(`Serply Error: ${e.message}`);
                return { response: null, error: e.message };
              });

            if (error)
              return `There was an error searching for content. ${error}`;

            const data = [];
            response.results?.forEach((searchResult) => {
              const { title, link, description } = searchResult;
              data.push({
                title,
                link,

View on GitHub (pinned to 526360e320)

Solutions

  1. Generate a new key from the Serly dashboard and update AGENT_SERLY_API_KEY.
  2. Verify the account associated with the key is active and in good standing.
  3. Confirm the key has no leading/trailing whitespace (common when copied from a dashboard).
  4. Test the key directly: curl -H 'X-API-KEY: <key>' 'https://api.serply.io/v1/search/q=test'.

Example fix

// before
if (data?.message === "Unauthorized")
  throw new Error("Unauthorized. Please double check your AGENT_SERLY_API_KEY");

// improved — surface the response body for diagnosis
if (data?.message === "Unauthorized") {
  throw new Error(
    `Serly rejected the API key. Verify AGENT_SERLY_API_KEY is valid and active. Response: ${JSON.stringify(data)}`
  );
}
Defensive patterns

Strategy: validation

Validate before calling

// Serly returns 200 OK with {message:'Unauthorized'} for invalid keys.
// Pre-validate the key format (length, no whitespace) before the request.
const key = process.env.AGENT_SERLY_API_KEY;
if (!key || key.trim().length < 10) {
  throw new Error("AGENT_SERLY_API_KEY appears to be missing or too short.");
}

Try / catch

try {
  const results = await serlySearch(query);
  return results;
} catch (e) {
  if (e.message.includes("Unauthorized") && e.message.includes("SERLY")) {
    return "Serly rejected the API key. Regenerate it from the Serly dashboard and update AGENT_SERLY_API_KEY.";
  }
  throw e;
}

Prevention

When it happens

Trigger: AGENT_SERLY_API_KEY is set but invalid, revoked, or belongs to a deactivated account. Serly accepts the request at the HTTP layer (200) but rejects the key at the application layer, returning the Unauthorized message in the body. This cannot be caught by HTTP status alone.

Common situations: Key was rotated but the old one is still in the environment; key from a test account used in production; account suspended but API still responding 200; typo in the key that happens to be syntactically plausible.

Understand the failure class

Related errors


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