JuliusBrussee/caveman · error · AgentMcpHTTPError
cave_auth_required
cave_auth_required
Error message
Not logged in. Run `caveman login` or set CAVE_TOKEN for headless use.
What it means
agentMcpRequest() performs authenticated API calls against the Cave backend. When the local config has no stored token, it throws an AgentMcpHTTPError with code `cave_auth_required` (HTTP 401) telling the user to run `caveman login` or set CAVE_TOKEN.
Solutions
- Run `caveman login` to store a token
- Set the CAVE_TOKEN environment variable in the shell/CI environment
- Verify the config file still contains the token (`caveman whoami` or inspect config)
- Re-authenticate if the token was revoked or expired
Example fix
// before (CI step)
- run: caveman agent sync
// after
- run: |
export CAVE_TOKEN=${{ secrets.CAVE_TOKEN }}
caveman agent sync Defensive patterns
Strategy: try-catch
Validate before calling
const cfg = await config();
if (!cfg.token && !process.env.CAVE_TOKEN) { console.error('Not authenticated: run `caveman login` or set CAVE_TOKEN'); process.exit(1); } Type guard
const isAuthError = (e: unknown): e is AgentMcpHTTPError => e instanceof AgentMcpHTTPError && e.code === 'cave_auth_required';
Try / catch
try { return await agentMcpRequest(path, opts); } catch (e) {
if (isAuthError(e)) { console.error('Run `caveman login` or set CAVE_TOKEN.'); process.exit(1); }
throw e;
} Prevention
- Run `caveman login` once per machine before scripted use
- Inject CAVE_TOKEN from a secret store in CI
- Check auth with a cheap command (whoami/status) before long workflows
- Alert on config resets that drop the stored token
When it happens
Trigger: Any CLI/agent command that reaches the MCP HTTP layer while `cfg.token` is empty: fresh install, CI container without login, expired/removed credentials, or CAVE_TOKEN unset in the environment.
Common situations: Running in a headless CI job where interactive `caveman login` is impossible, switching machines and forgetting to log in, or a config reset that wiped the stored token.
Related errors
- device login timed out before approval
- eval evidence import failed
- caveman-cloud MCP changed after setup; refusing destructive…
- caveman-cloud MCP changed during interrupted setup…
- caveman-cloud MCP changed during interrupted removal…
AI-assisted analysis of JuliusBrussee/caveman@3ee70a1026 (2026-09-20).
Data as JSON: /api/errors/f6909eabce4b15fc.
Report an issue: GitHub.
Appendix: source
Thrown at packages/cli/src/index.ts:18372
this.name = "AgentMcpHTTPError";
this.code = code;
this.status = status;
}
}
function agentMcpTimeoutMS(): number {
const raw = process.env.CAVE_AGENT_TOOL_TIMEOUT_MS ?? "30000";
const value = Number(raw);
return Number.isSafeInteger(value) && value >= 100 && value <= 120_000 ? value : 30_000;
}
async function agentMcpRequest(
path: string,
options: { method?: "GET" | "POST"; body?: JSONObject } = {},
): Promise<JSONValue> {
const cfg = await config();
if (!cfg.token) {
throw new AgentMcpHTTPError(
"Not logged in. Run `caveman login` or set CAVE_TOKEN for headless use.",
"cave_auth_required",
401,
);
}
let response: Response;
try {
const request: RequestInit = {
method: options.method ?? "GET",
signal: AbortSignal.timeout(agentMcpTimeoutMS()),
headers: {
authorization: `Bearer ${cfg.token}`,
...(options.method === "POST"
? { "content-type": "application/json", "x-cave-csrf": "cli" }
: {}),
},
};
if (options.method === "POST") request.body = JSON.stringify(options.body ?? {});View on GitHub (pinned to 3ee70a1026)