JuliusBrussee/caveman · error · AgentMcpHTTPError
cave_request_failed
cave_request_failed
Error message
Caveman API request failed (${response.status}). What it means
Thrown by agentMcpRequest() after receiving an HTTP response with a non-ok status when the response body carries no usable error message or code. The client first tries to surface the API's structured error envelope (body.error.message or body.message) and envelope code; if none is a string it falls back to this generic message with code cave_request_failed. It represents a real HTTP-level failure of a Caveman API call whose server-side detail was lost.
Solutions
- Log/inspect response.status and the raw response body to identify the real server error.
- Check the gateway version matches the CLI; upgrade the gateway so it returns structured error envelopes.
- Verify the request path and payload match the current Caveman API schema.
- If it is a proxy error page (502/503), fix the reverse proxy / upstream gateway availability.
Example fix
// before
try { await agentMcpRequest("POST", "/v1/agent/run", body); }
catch (e) { console.log(e.message); } // "Caveman API request failed (502)."
// after
try { await agentMcpRequest("POST", "/v1/agent/run", body); }
catch (e) { console.error(e.message, e.statusCode, await rawBody); } // inspect status + raw body Defensive patterns
Strategy: try-catch
Validate before calling
const res = await fetch(`${baseURL}${path}`);
if (!res.ok) {
const text = await res.text();
console.error(`Caveman API ${res.status}:`, text.slice(0, 500)); // inspect real cause
} Type guard
function isAgentMcpHTTPError(e: unknown): e is Error & { statusCode?: number; code: string } {
return e instanceof Error && e.name === "AgentMcpHTTPError";
} Try / catch
try {
await agentMcpRequest("POST", path, body);
} catch (e) {
if (isAgentMcpHTTPError(e)) {
if (e.code === "cave_request_failed") {
console.error(`HTTP failure (${e.statusCode ?? "?"}): check gateway version and request schema`, e.message);
}
} else throw e;
} Prevention
- Keep gateway and CLI versions in sync so error envelopes are structured
- Validate request payloads against the current API schema
- Log response.status plus raw body on any non-ok response
- Check reverse-proxy error pages (502/503) before blaming the CLI
When it happens
Trigger: Any Caveman API request returning response.ok === false (4xx/5xx) where the parsed JSON body has neither body.error.message, body.message (strings) nor body.error/envelope.code to report.
Common situations: Gateway returning an HTML/plain-text error page (e.g. 502 from a reverse proxy) that fails JSON parse to {}, hitting a wrong path that yields an opaque 404, or an older gateway version not emitting the error envelope.
Understand the failure class
Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.
Related errors
- cave request failed ( )
- registration failed: HTTP
- tool search failed with HTTP
- awscreds: sts assume role with web identity failed
- binary download failed: HTTP
AI-assisted analysis of JuliusBrussee/caveman@3ee70a1026 (2026-09-20).
Data as JSON: /api/errors/d2e0f7f79a0bad97.
Report an issue: GitHub.
Appendix: source
Thrown at packages/cli/src/index.ts:18409
response = await fetch(`${cfg.baseURL}${path}`, request);
} catch (error) {
const timedOut = error instanceof Error && error.name === "TimeoutError";
throw new AgentMcpHTTPError(
timedOut
? `Caveman API request timed out after ${agentMcpTimeoutMS()}ms.`
: error instanceof Error
? error.message
: "Caveman API request failed.",
timedOut ? "cave_agent_tool_timeout" : "cave_network_error",
);
}
const body = await response.json().catch(() => ({})) as JSONObject;
if (!response.ok) {
const envelope = body.error && typeof body.error === "object" && !Array.isArray(body.error)
? body.error as Record<string, unknown>
: {};
const flatCode = typeof body.error === "string" ? body.error : undefined;
throw new AgentMcpHTTPError(
typeof envelope.message === "string"
? envelope.message
: typeof body.message === "string"
? body.message
: `Caveman API request failed (${response.status}).`,
typeof envelope.code === "string" ? envelope.code : flatCode ?? "cave_request_failed",
response.status,
);
}
return body;
}
async function agentMcpProjectId(): Promise<string> {
const cfg = await config();
if (cfg.projectId) return cfg.projectId;
const projects = await agentMcpRequest("/api/v1/projects");
const projectObject = projects && typeof projects === "object" && !Array.isArray(projects)
? projectsView on GitHub (pinned to 3ee70a1026)