{"record":{"id":"835dc18d2e1bf9c4","repo":"JuliusBrussee/caveman","slug":"profile-display-name-integration-is-degraded-r","errorCode":null,"errorMessage":"${profile.display_name} integration is degraded; run `caveman doctor ${agent}` before changing it","messagePattern":"(.+?) integration is degraded; run `caveman doctor (.+?)` before changing it","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/cli/src/index.ts","lineNumber":7959,"sourceCode":"  const profiles = detected\n    ? AGENTS.filter((agent) => (agent.id === \"claude\" || agent.id === \"codex\" || agent.id === \"hermes\" || agent.id === \"gemini\" || agent.id === \"opencode\" || agent.id === \"pi\" || agent.id === \"aider\") && which(binOf(agent)))\n    : AGENTS.filter((agent) => agent.id === target && (agent.id === \"claude\" || agent.id === \"codex\" || agent.id === \"hermes\" || agent.id === \"gemini\" || agent.id === \"opencode\" || agent.id === \"pi\" || agent.id === \"aider\"));\n  if (profiles.length === 0) {\n    console.error(detected ? \"no supported native agent detected on PATH\" : `caveman enable: supported agents are claude, codex, hermes, gemini, opencode, pi, and aider (got ${target ?? \"\"})`);\n    process.exit(1);\n  }\n  const gw = gatewayURL();\n  for (const profile of profiles) {\n    const agent = profile.id as NativeAgent;\n    const outcome = withIntegrationLock(agent, () => {\n      recoverPendingNativeInstallUnlocked(agent);\n      if (!which(binOf(profile))) throw new Error(`${profile.display_name} not found on PATH`);\n      const mcpBinary = agent === \"aider\" ? undefined : nativeMcpBinaryRequired();\n      nativeProxyBinaryRequired(gw);\n      const existing = nativeIntegrationStatus(agent);\n      if (existing.installed) {\n        if (existing.state === \"installed\") return \"already\" as const;\n        throw new Error(`${profile.display_name} integration is degraded; run \\`caveman doctor ${agent}\\` before changing it`);\n      }\n      const mutations = nativeMutationsFor(agent, gw, mcpBinary);\n      const route = mutations.find((item) => typeof item.owned?.route === \"string\")?.owned?.route;\n      process.stderr.write(`caveman enable ${agent}: planned user-scoped writes\\n`);\n      for (const mutation of mutations) process.stderr.write(`  ${mutation.kind}: ${mutation.file}\\n`);\n      if (typeof route === \"string\") process.stderr.write(`  routing: ${route}\\n`);\n      process.stderr.write(agent === \"aider\" ? \"  recovery MCP: unavailable in Aider\\n\" : `  recovery MCP: ${mcpBinary}\\n`);\n      process.stderr.write(agent === \"aider\"\n        ? `  Core: read-only ${aiderCorePath()}; lifecycle/tool interception unavailable; Ledger observational\\n`\n        : agent === \"pi\"\n          ? `  lifecycle/Core/tool rewrite: bundled Pi extension -> ${nativeHookCommand(agent)}\\n`\n          : `  lifecycle/Core/tool rewrite: ${nativeHookCommand(agent)}${agent === \"hermes\" ? \" via native plugin\" : ` + ${cavemanBinForHook()} shrink-hook`}\\n`);\n      applyNativeMutations(agent, profile, mutations);\n      return \"enabled\" as const;\n    });\n    if (outcome === \"already\") {\n      process.stderr.write(`${mark(\"ok\")} ${profile.display_name}: ${agent === \"aider\" ? \"shallow\" : \"native\"} Caveman already enabled\\n`);\n      continue;","sourceCodeStart":7941,"sourceCodeEnd":7977,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/5184b3d11ac6a1acb7d44b9bfaa31698157cff97/packages/cli/src/index.ts#L7941-L7977","documentation":"enable refuses to mutate an integration that nativeIntegrationStatus() reports as installed but degraded - a journal exists, yet pack version, owned blocks, the route, the proxy capability (native_runtime_v1), recovery MCP, or a pending transaction no longer match. Mutating a degraded install without repair could orphan the existing journal, so the command points at `caveman doctor <agent>` first.","triggerScenarios":"`caveman enable <agent>` while the agent is already enabled and: caveman was upgraded (pack_version mismatch), the gateway URL changed (owned route no longer equals appendUrlPath(gatewayURL(), ...)), the proxy is old or missing the native_runtime_v1 capability, the caveman-mcp binary is gone, or .pending-<agent>.json exists (transaction_pending forces degraded).","commonSituations":"Re-running setup scripts after an upgrade; switching CAVE_GATEWAY_URL or ports; moving between local proxy and managed gateway; a previously interrupted enable.","solutions":["Run `caveman doctor <agent>` to see which component is degraded (routing / hooks / core / recovery / shared runtime).","Run `caveman doctor <agent> --fix` - it recovers pending transactions, repairs drifted installs, or re-enables as needed.","If the gateway moved on purpose, keep the new URL and let doctor --fix rewrite the route to match it.","Only after doctor reports state 'installed' (or 'available' after disable) should enable/disable changes proceed."],"exampleFix":"// before\n$ caveman enable codex\nError: Codex integration is degraded; run `caveman doctor codex` before changing it\n\n// after\n$ caveman doctor codex --fix\n$ caveman enable codex   # now reports 'already' or proceeds cleanly","handlingStrategy":"validation","validationCode":"import { spawnSync } from 'node:child_process';\nconst agent = 'codex';\nconst r = spawnSync('caveman', ['doctor', agent], { encoding: 'utf8' });\n// doctor exits non-zero when state is degraded or unavailable\nif (r.status !== 0) {\n  console.error(`${agent} integration not healthy; run: caveman doctor ${agent} --fix`);\n  process.exit(1);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["In setup scripts, replace bare `caveman enable <agent>` with `caveman doctor <agent> --fix` - it is idempotent and repairs degraded installs","After changing gateway URLs or upgrading caveman, run doctor before further enable/disable calls","Watch `caveman status` output for degraded integrations instead of re-running enable"],"tags":["degraded","doctor","enable","integrations"],"backgroundTag":"degraded-integration-state","analyzedSha":"5184b3d11ac6a1acb7d44b9bfaa31698157cff97","analyzedAt":"2026-08-18T03:14:35.516Z","contentChangedAt":"2026-08-18T03:14:35.516Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}