JuliusBrussee/caveman · error · Error

caveman: remote gateway key revocation failed (HTTP ${respon

Error message

caveman: remote gateway key revocation failed (HTTP ${response.status}); credentials kept — retry `caveman logout`

What it means

During `caveman logout`, the request to revoke the gateway key on the server returned a non-2xx status. Local credentials are deliberately kept (not deleted) so the user can retry; a failed revocation with deleted credentials would leave a live key on the server.

Source

Thrown at packages/cli/src/index.ts:9452

	const cfg = await config();
	const externalToken = Boolean(process.env.CAVE_TOKEN);
	if (cfg.token && (!cfg.logoutPendingLocalCleanup || externalToken)) {
	  if (cfg.projectId && cfg.gatewayKeyId) {
	    let response: Response;
	    try {
	      response = await fetch(`${cfg.baseURL}/api/v1/projects/${encodeURIComponent(cfg.projectId)}/keys/${encodeURIComponent(cfg.gatewayKeyId)}/revoke`, {
	        method: "POST",
	        headers: { authorization: `Bearer ${cfg.token}`, "content-type": "application/json", "x-cave-csrf": "cli" },
	        body: "{}",
	        signal: AbortSignal.timeout(5000),
	      });
	    } catch {
	      throw new Error("caveman: remote gateway key revocation was unavailable; credentials kept — retry `caveman logout`");
	    }
	    if (!response.ok) {
	      const body = await response.json().catch(() => null) as { error?: { code?: unknown } } | null;
	      const alreadyRevoked = response.status === 404 && body?.error?.code === "cave_key_not_found";
	      if (!alreadyRevoked) throw new Error(`caveman: remote gateway key revocation failed (HTTP ${response.status}); credentials kept — retry \`caveman logout\``);
	    }
	  }
	  const headers: Record<string, string> = {
	    authorization: `Bearer ${cfg.token}`,
	    "x-cave-client": "cli",
	  };
	  const request: RequestInit = {
	    method: "POST",
	    headers,
	    signal: AbortSignal.timeout(5000),
	  };
	  if (cfg.refreshToken) {
	    headers["content-type"] = "application/json";
	    request.body = JSON.stringify({ refresh_token: cfg.refreshToken });
	  }
	  let response: Response;
	  try {
	    response = await fetch(`${cfg.baseURL}/api/v1/auth/logout`, request);

View on GitHub (pinned to 5184b3d11a)

Solutions

  1. Retry `caveman logout`; check the HTTP status in the message (5xx → server issue)
  2. If retries fail, revoke the key via the cloud dashboard
Defensive patterns

Strategy: retry

When it happens

Trigger: Thrown at packages/cli/src/index.ts:8607 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of JuliusBrussee/caveman@5184b3d11a (2026-08-18). Data as JSON: /api/errors/b0e5937619ad2be2. Report an issue: GitHub.