JuliusBrussee/caveman · error

caveman agent: Cave Runtime failed to start (${error instanc

Error message

caveman agent: Cave Runtime failed to start (${error instanceof Error ? error.message : String(error)})

What it means

Thrown when constructing the spawn invocation for `caveman start` itself fails — portableInvocation() threw before any child process existed, and the original error message is embedded. This is a CLI-resolution/platform problem, not a gateway problem: the runtime wanted to boot the loopback gateway but could not even build a valid command for the Caveman CLI binary (CAVEMAN_CLI_BIN, default "caveman").

Source

Thrown at packages/agent/src/runtime.ts:5240

        `cave_gateway_identity_unverified: non-loopback gateway ${gatewayURL} requires https`,
      );
    }
    const identity = await gatewayIdentity(gatewayURL, fetchImpl);
    if (identity !== undefined) return identity.providerBilling;
    throw new Error(
      `cave_gateway_identity_unverified: ${gatewayURL}/health/ready did not identify as caveman-proxy`,
    );
  }
  const readyBilling = await runtimeReady(gatewayURL, fetchImpl);
  if (readyBilling !== undefined) return readyBilling;

  const command = process.env.CAVEMAN_CLI_BIN ?? "caveman";
  let startupFailure: Error | undefined;
  let invocation;
  try {
    invocation = portableInvocation(command, ["start"], { env: buildRuntimeControlEnv() });
  } catch (error) {
    throw new Error(`caveman agent: Cave Runtime failed to start (${error instanceof Error ? error.message : String(error)})`);
  }
  const child = spawn(invocation.command, [...invocation.args], {
    detached: true,
    windowsHide: true,
    stdio: "ignore",
    env: buildRuntimeControlEnv(),
  });
  child.once("error", (error) => {
    startupFailure = (error as NodeJS.ErrnoException).code === "ENOENT"
      ? new Error(
        "caveman agent: Caveman CLI not found; run npm install, then caveman setup --install",
      )
      : new Error(`caveman agent: Cave Runtime failed to start (${error.message})`);
  });
  child.once("exit", (code, signal) => {
    if (startupFailure !== undefined || code === 0) return;
    startupFailure = new Error(
      `caveman agent: Cave Runtime failed to start (caveman start exited ${signal ?? code}); run caveman setup --install`,

View on GitHub (pinned to 766dce6b13)

Solutions

  1. Unset or fix CAVEMAN_CLI_BIN so it names a working caveman executable (verify: caveman version)
  2. Reinstall the runtime: caveman setup --install (or reinstall the package that ships the CLI)
  3. Read the embedded parenthesized error — it carries the underlying failure (ENOENT-style path problems, permission, platform)
  4. Run caveman doctor: it reports a missing runtime CLI as a WARN with execution_mode, confirming this layer before you debug the gateway

Example fix

# before
export CAVEMAN_CLI_BIN=/opt/broken/caveman # bad path

# after
unset CAVEMAN_CLI_BIN
caveman version && caveman setup --install
Defensive patterns

Strategy: validation

Validate before calling

import { spawnSync } from 'node:child_process';
function assertCavemanCLI() {
  const bin = process.env.CAVEMAN_CLI_BIN ?? 'caveman';
  const probe = spawnSync(bin, ['version'], { encoding: 'utf8' });
  if (probe.error) throw new Error('caveman CLI unavailable: ' + bin);
}

Try / catch

try {
  await run(agent, options);
} catch (error) {
  if (error instanceof Error && error.message.includes('Cave Runtime failed to start')) {
    // embedded parenthesized reason carries the underlying invocation error
    delete process.env.CAVEMAN_CLI_BIN; // fall back to the default binary
    await reinstallRuntime(); // caveman setup --install
    return run(agent, options);
  }
  throw error;
}

Prevention

When it happens

Trigger: Loopback gateway is not ready, runtime tries portableInvocation(CAVEMAN_CLI_BIN ?? 'caveman', ['start'], ...) and that setup throws — e.g. the env-overridden CAVEMAN_CLI_BIN points somewhere unusable, or the invocation wrapper cannot be built on this platform/environment.

Common situations: CAVEMAN_CLI_BIN set to a wrong/nonexistent path in CI; partial npm/pnpm install where the caveman CLI shim exists but is broken; running in a minimal container where the spawn wrapper prerequisites (shell/path resolution) are missing.

Related errors


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