Mintplex-Labs/anything-llm · error · Error
API Call failed
Error message
API Call failed: ${error.message} What it means
The catch-all wrapper at the bottom of executeApiCall: every failure in the API Call block — network-level fetch errors (DNS, ECONNREFUSED, TLS), the 'HTTP error! status: N' throw above, and safeJsonParse failures ('Failed to parse output from API call block') — is logged with console.error and rethrown as 'API Call failed: <original message>'. The root cause survives only inside the message suffix after the colon.
Solutions
- Read the text after 'API Call failed:' — it preserves the underlying cause ('fetch failed', 'HTTP error! status: N', 'Failed to parse output...').
- For 'fetch failed', test connectivity from the same host/container: curl -v <url>.
- For parse failures, check whether the endpoint returns JSON for the given method/headers, or switch the block to consume the text response.
- Verify the URL string produced after variable substitution (see the 'Sending body/URL' introspect lines).
Defensive patterns
Strategy: try-catch
Validate before calling
function apiCallBlockConfigOk(config) {
try {
const u = new URL(config.url);
return /^https?:$/.test(u.protocol);
} catch {
return false;
}
} Try / catch
try {
await runFlow();
} catch (e) {
if (e.message.startsWith("API Call failed:")) {
const cause = e.message.slice("API Call failed:".length).trim();
// cause is the real reason: 'fetch failed' | 'HTTP error! status: N' | parse failure
if (cause.includes("fetch failed")) return reportNetwork(cause);
if (/HTTP error! status: 4\d\d/.test(cause)) return reportConfig(cause);
return reportUpstream(cause);
}
throw e;
} Prevention
- Always unwrap the suffix after 'API Call failed:' before debugging — the root cause lives there.
- Confirm the target returns JSON when the block expects a parsed result, or handle text responses.
- Verify container egress (DNS, proxy, firewall) for every new external endpoint used by a flow.
When it happens
Trigger: Any API Call block execution where fetch throws (invalid URL scheme, unreachable host, certificate error), the response is non-2xx, or the response text is not valid JSON when a JSON result was expected. The wrapped message nests: 'API Call failed: HTTP error! status: 404' or 'API Call failed: fetch failed'.
Common situations: Typo'd URL or missing https://; server cannot resolve/reach the target (Docker network isolation); self-signed certificate on an internal endpoint; remote returns HTML error page that JSON-parsing rejects; proxy/firewall blocking egress from the container.
Understand the failure class
Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.
Related errors
- HTTP error! status
- LLM processing failed
- An error occurred while deleting the model
- Could not validate login.
- data.message || "Could not update slash command preset."
AI-assisted analysis of Mintplex-Labs/anything-llm@f92433b4ea (2026-08-18).
Data as JSON: /api/errors/4a09bbadc26c37d8.
Report an issue: GitHub.
Appendix: source
Thrown at server/utils/agentFlows/executors/api-call.js:60
}
try {
introspect(`Sending body to ${url}: ${requestConfig?.body || "No body"}`);
const response = await fetch(url, requestConfig);
if (!response.ok) {
introspect(`Request failed with status ${response.status}`);
throw new Error(`HTTP error! status: ${response.status}`);
}
introspect(`API call completed`);
const responseText = await response.text();
try {
// JSON bodies parse into values; anything else (plain text, HTML,
// empty bodies) is passed through verbatim. We intentionally avoid
// safeJsonParse here so non-JSON bodies are never "repaired" into
// invented JSON or reduced to an embedded JSON substring.
return JSON.parse(responseText);
} catch {
return responseText;
}
} catch (error) {
console.error(error);
throw new Error(`API Call failed: ${error.message}`);
}
}
module.exports = executeApiCall;
View on GitHub (pinned to f92433b4ea)