{"record":{"id":"456479d273eadbc6","repo":"JuliusBrussee/caveman","slug":"cave-transform-registry-unavailable","errorCode":"cave_transform_registry_unavailable","errorMessage":"cave_transform_registry_unavailable: run caveman setup or set CAVEMAN_ENGINE_BIN (${error instanceof Error ? error.message : String(error)})","messagePattern":"cave_transform_registry_unavailable: run caveman setup or set CAVEMAN_ENGINE_BIN \\((.+?)\\)","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/agent/src/cli.ts","lineNumber":1132,"sourceCode":"      throw new Error(\"registry output has no valid registry_sha256\");\n    }\n    if (!Array.isArray(parsed.capabilities) || parsed.capabilities.length === 0) {\n      throw new Error(\"registry output has no capabilities\");\n    }\n    const capabilities = parsed.capabilities.map((capability): TransformCapability => {\n      if (typeof capability.transform_id !== \"string\" ||\n          !Array.isArray(capability.eligible_segment_kinds) ||\n          capability.eligible_segment_kinds.some((kind) => typeof kind !== \"string\")) {\n        throw new Error(\"registry output has invalid capability\");\n      }\n      return {\n        transformID: capability.transform_id,\n        segmentKinds: capability.eligible_segment_kinds as TransformCapability[\"segmentKinds\"],\n      };\n    });\n    return { sha256: parsed.registry_sha256, capabilities };\n  } catch (error) {\n    throw new Error(\n      `cave_transform_registry_unavailable: run caveman setup or set CAVEMAN_ENGINE_BIN (${error instanceof Error ? error.message : String(error)})`,\n    );\n  }\n}\n\nasync function engineEntitled(): Promise<boolean> {\n  const command = process.env.CAVEMAN_CLI_BIN ?? \"caveman\";\n  try {\n    const env = buildRuntimeControlEnv();\n    const invocation = portableInvocation(command, [\"status\", \"--json\"], { env });\n    const { stdout } = await execFileAsync(invocation.command, [...invocation.args], {\n      encoding: \"utf8\",\n      env,\n      maxBuffer: 2 << 20,\n      timeout: 10_000,\n    });\n    const parsed = JSON.parse(stdout) as { mode?: unknown; seat?: { entitled?: unknown } };\n    return parsed.seat?.entitled === true && parsed.mode === \"compress\";","sourceCodeStart":1114,"sourceCodeEnd":1150,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/3ee70a102609e550bd2e68004bf5990a9341c851/packages/agent/src/cli.ts#L1114-L1150","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before (shell)\ncaveman build  # ENOENT: caveman-engine not found\n// after\nexport CAVEMAN_ENGINE_BIN=/opt/caveman/bin/caveman-engine\ncaveman build","handlingStrategy":"try-catch","validationCode":"import { accessSync, constants } from \"node:fs\";\nconst bin = process.env.CAVEMAN_ENGINE_BIN ?? \"caveman-engine\";\ntry {\n  accessSync(bin.includes(\"/\") ? bin : which(bin) ?? bin, constants.X_OK);\n} catch {\n  console.error(`engine binary '${bin}' not executable/found — run caveman setup or set CAVEMAN_ENGINE_BIN`);\n}","typeGuard":null,"tryCatchPattern":"try {\n  await loadTransformRegistry();\n} catch (error) {\n  if ((error as Error).message.startsWith(\"cave_transform_registry_unavailable\")) {\n    console.error(\"Engine unavailable:\", (error as Error).message);\n    // degrade (observe-only) or provision:\n    await runCavemanSetup();\n    return await loadTransformRegistry();\n  }\n  throw error;\n}","preventionTips":["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"],"tags":["engine","registry","missing-dependency","subprocess","environment"],"backgroundTag":"missing-dependency","analyzedSha":"3ee70a102609e550bd2e68004bf5990a9341c851","analyzedAt":"2026-09-20T15:53:39.229Z","contentChangedAt":"2026-09-20T15:53:39.229Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}