JuliusBrussee/caveman · error
cave_transform_registry_unavailable
cave_transform_registry_unavailable
Error message
cave_transform_registry_unavailable: run caveman setup or set CAVEMAN_ENGINE_BIN (${error instanceof Error ? error.message : String(error)}) What it means
loadTransformRegistry() wraps every failure of the engine registry lookup (spawn failure, timeout, bad JSON, any of the validation throws above) into a single error 'cave_transform_registry_unavailable: run caveman setup or set CAVEMAN_ENGINE_BIN (...)' with the original message as context. The framework needs the transform registry to compute lock identity and plan routes, so an unavailable engine fails closed with a remediation hint.
Solutions
- Run 'caveman setup' to install the engine binary and registry (the error's prescribed fix)
- Set CAVEMAN_ENGINE_BIN to the absolute path of a working caveman-engine binary
- Verify 'caveman-engine registry' runs manually and emits valid JSON quickly (<10s)
- Check PATH in CI/shell so the engine is reachable, or fix permissions on the binary
Example fix
// before (shell) caveman build # ENOENT: caveman-engine not found // after export CAVEMAN_ENGINE_BIN=/opt/caveman/bin/caveman-engine caveman build
Defensive patterns
Strategy: try-catch
Validate before calling
import { accessSync, constants } from "node:fs";
const bin = process.env.CAVEMAN_ENGINE_BIN ?? "caveman-engine";
try {
accessSync(bin.includes("/") ? bin : which(bin) ?? bin, constants.X_OK);
} catch {
console.error(`engine binary '${bin}' not executable/found — run caveman setup or set CAVEMAN_ENGINE_BIN`);
} Try / catch
try {
await loadTransformRegistry();
} catch (error) {
if ((error as Error).message.startsWith("cave_transform_registry_unavailable")) {
console.error("Engine unavailable:", (error as Error).message);
// degrade (observe-only) or provision:
await runCavemanSetup();
return await loadTransformRegistry();
}
throw error;
} Prevention
- Run 'caveman setup' as part of machine/CI provisioning
- Set CAVEMAN_ENGINE_BIN to an absolute path in CI and containers
- Keep engine startup under the 10s timeout; warm caches before lock checks
- Verify PATH in the exact shell/user the CLI runs under
When it happens
Trigger: Any failure inside loadTransformRegistry: the engine binary is not on PATH (ENOENT), CAVEMAN_ENGINE_BIN points at a missing/non-executable file, the registry call exceeds the 10s timeout or 2MiB buffer, stdout is not valid JSON, or one of the registry_sha256/capabilities validation checks throws.
Common situations: Fresh machine where 'caveman setup' was never run; engine uninstalled or moved; CI container missing the engine; slow engine exceeding the 10s timeout; shadowing 'caveman-engine' on PATH with an unrelated program.
Understand the failure class
Background: "not installed", "pip install", "required for": how missing-dependency errors surface across open-source libraries — this error's family across 34 libraries.
Related errors
- registry output has invalid capability
- registry output has no valid registry_sha256
- cave_transform_registry_unavailable: run caveman setup or…
- registry output has no capabilities
- bounded_response_unavailable
AI-assisted analysis of JuliusBrussee/caveman@3ee70a1026 (2026-09-20).
Data as JSON: /api/errors/456479d273eadbc6.
Report an issue: GitHub.
Appendix: source
Thrown at packages/agent/src/cli.ts:1132
throw new Error("registry output has no valid registry_sha256");
}
if (!Array.isArray(parsed.capabilities) || parsed.capabilities.length === 0) {
throw new Error("registry output has no capabilities");
}
const capabilities = parsed.capabilities.map((capability): TransformCapability => {
if (typeof capability.transform_id !== "string" ||
!Array.isArray(capability.eligible_segment_kinds) ||
capability.eligible_segment_kinds.some((kind) => typeof kind !== "string")) {
throw new Error("registry output has invalid capability");
}
return {
transformID: capability.transform_id,
segmentKinds: capability.eligible_segment_kinds as TransformCapability["segmentKinds"],
};
});
return { sha256: parsed.registry_sha256, capabilities };
} catch (error) {
throw new Error(
`cave_transform_registry_unavailable: run caveman setup or set CAVEMAN_ENGINE_BIN (${error instanceof Error ? error.message : String(error)})`,
);
}
}
async function engineEntitled(): Promise<boolean> {
const command = process.env.CAVEMAN_CLI_BIN ?? "caveman";
try {
const env = buildRuntimeControlEnv();
const invocation = portableInvocation(command, ["status", "--json"], { env });
const { stdout } = await execFileAsync(invocation.command, [...invocation.args], {
encoding: "utf8",
env,
maxBuffer: 2 << 20,
timeout: 10_000,
});
const parsed = JSON.parse(stdout) as { mode?: unknown; seat?: { entitled?: unknown } };
return parsed.seat?.entitled === true && parsed.mode === "compress";View on GitHub (pinned to 3ee70a1026)