{"record":{"id":"cdae627986f8d40b","repo":"affaan-m/ECC","slug":"refusing-to-trust-managed-install-state-at-plan-cdae62","errorCode":null,"errorMessage":"Refusing to trust managed install-state at ${plan.installStatePath}: recorded root does not match the current install root.","messagePattern":"Refusing to trust managed install-state at (.+?): recorded root does not match the current install root\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/lib/multi-harness-setup.js","lineNumber":112,"sourceCode":"    );\n  }\n}\n\nfunction assertPriorInstallStateMatchesPlan(state, plan) {\n  const target = state.target || {};\n  const adapter = plan.adapter || {};\n  if (\n    target.id !== adapter.id\n    || target.target !== adapter.target\n    || target.kind !== adapter.kind\n  ) {\n    throw new Error(\n      `Refusing to trust managed install-state at ${plan.installStatePath}: `\n      + 'target identity does not match the current Kimi install plan.'\n    );\n  }\n  if (!pathsMatch(target.root, plan.targetRoot)) {\n    throw new Error(\n      `Refusing to trust managed install-state at ${plan.installStatePath}: `\n      + 'recorded root does not match the current install root.'\n    );\n  }\n  if (!pathsMatch(target.installStatePath, plan.installStatePath)) {\n    throw new Error(\n      `Refusing to trust managed install-state at ${plan.installStatePath}: `\n      + 'recorded install-state path does not match the current install-state path.'\n    );\n  }\n}\n\nfunction readOwnedDestinations(plan, dependencies) {\n  if (!plan.installStatePath) {\n    return { destinations: new Set(), stateFingerprint: { exists: false, sha256: null } };\n  }\n  try {\n    assertSafeInstallOperation(plan, { destinationPath: plan.installStatePath });","sourceCodeStart":94,"sourceCodeEnd":130,"githubUrl":"https://github.com/affaan-m/ECC/blob/01e15490f04e29cfefe3896951f43db46994d8ee/scripts/lib/multi-harness-setup.js#L94-L130","documentation":"Thrown by assertPriorInstallStateMatchesPlan when the install-state's recorded target.root (canonicalized via realpathNearestExisting) does not equal plan.targetRoot. ECC scopes ownership to a concrete project root; a state recorded under a different root cannot vouch for files in the current project. This blocks attacks/mistakes where a state file is copied or symlinked from elsewhere to claim ownership it does not have.","triggerScenarios":"Fires when pathsMatch(target.root, plan.targetRoot) is false inside readOwnedDestinations. Happens if the project was moved/cloned to a new path but the old install-state was kept, if plan.targetRoot was computed from a different cwd/HOME than when the state was written, or if symlinks cause realpath to resolve the same logical path to different canonical strings.","commonSituations":"Copying a project folder that includes .claude/ and continuing the install from the new location; running ECC from a container with a different mount path than the host; HOME or cwd resolving differently between the preview run and the apply run; symlinked project roots where one side resolved and the other did not.","solutions":["Delete plan.installStatePath and re-run createMultiHarnessPlan so target.root is recorded for the current plan.targetRoot.","Run preview and apply from the same working directory with the same HOME so plan.targetRoot resolves identically.","If the project was moved intentionally, treat it as a fresh install (discard old state).","Inspect target.root vs plan.targetRoot in the JSON to confirm the path mismatch is the cause and not a realpath/symlink artifact."],"exampleFix":"// before: project moved from ~/dev/app to ~/code/app, old state retained\n// state.target.root = '/home/me/dev/app'\n// plan.targetRoot      = '/home/me/code/app'\nawait applyMultiHarnessPlan(plan); // throws [282]\n\n// after: re-record state for the new root\nfs.rmSync(plan.installStatePath, { force: true });\nconst plan2 = await createMultiHarnessPlan(req);\nawait applyMultiHarnessPlan(plan2);","handlingStrategy":"validation","validationCode":"const fs = require('fs'); const path = require('path');\nfunction assertStateRootMatches(statePath, targetRoot) {\n  if (!fs.existsSync(statePath)) return;\n  const state = JSON.parse(fs.readFileSync(statePath, 'utf8'));\n  const recorded = path.resolve(state.target && state.target.root || '');\n  const current = path.resolve(targetRoot);\n  if (recorded !== current) {\n    throw new Error(`Install-state recorded root ${recorded} != current ${current}; remove the state or move the project back.`);\n  }\n}\nassertStateRootMatches(plan.installStatePath, plan.targetRoot);","typeGuard":"null","tryCatchPattern":"try {\n  await applyMultiHarnessPlan(plan);\n} catch (err) {\n  if (/recorded root does not match the current install root/.test(err.message)) {\n    fs.rmSync(plan.installStatePath, { force: true });\n    const fresh = await createMultiHarnessPlan(plan.request);\n    await applyMultiHarnessPlan(fresh);\n  } else throw err;\n}","preventionTips":["Run preview and apply from the same cwd so plan.targetRoot resolves identically.","After moving a project, delete its .claude/install-state.json and re-install.","Avoid symlinks that make realpath resolve the same path differently between runs.","Pass projectRoot explicitly to createManagedPlan rather than relying on cwd."],"tags":["install-state","target-root","ownership","path-canonicalization","kimi"],"backgroundTag":null,"analyzedSha":"01e15490f04e29cfefe3896951f43db46994d8ee","analyzedAt":"2026-08-13T00:31:08.655Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}