affaan-m/ECC · error · Error
Refusing to trust managed install-state at ${plan.installSta
Error message
Refusing to trust managed install-state at ${plan.installStatePath}: recorded root does not match the current install root. What it means
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.
Source
Thrown at scripts/lib/multi-harness-setup.js:112
);
}
}
function assertPriorInstallStateMatchesPlan(state, plan) {
const target = state.target || {};
const adapter = plan.adapter || {};
if (
target.id !== adapter.id
|| target.target !== adapter.target
|| target.kind !== adapter.kind
) {
throw new Error(
`Refusing to trust managed install-state at ${plan.installStatePath}: `
+ 'target identity does not match the current Kimi install plan.'
);
}
if (!pathsMatch(target.root, plan.targetRoot)) {
throw new Error(
`Refusing to trust managed install-state at ${plan.installStatePath}: `
+ 'recorded root does not match the current install root.'
);
}
if (!pathsMatch(target.installStatePath, plan.installStatePath)) {
throw new Error(
`Refusing to trust managed install-state at ${plan.installStatePath}: `
+ 'recorded install-state path does not match the current install-state path.'
);
}
}
function readOwnedDestinations(plan, dependencies) {
if (!plan.installStatePath) {
return { destinations: new Set(), stateFingerprint: { exists: false, sha256: null } };
}
try {
assertSafeInstallOperation(plan, { destinationPath: plan.installStatePath });View on GitHub (pinned to 01e15490f0)
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.
Example fix
// before: project moved from ~/dev/app to ~/code/app, old state retained
// state.target.root = '/home/me/dev/app'
// plan.targetRoot = '/home/me/code/app'
await applyMultiHarnessPlan(plan); // throws [282]
// after: re-record state for the new root
fs.rmSync(plan.installStatePath, { force: true });
const plan2 = await createMultiHarnessPlan(req);
await applyMultiHarnessPlan(plan2); Defensive patterns
Strategy: validation
Validate before calling
const fs = require('fs'); const path = require('path');
function assertStateRootMatches(statePath, targetRoot) {
if (!fs.existsSync(statePath)) return;
const state = JSON.parse(fs.readFileSync(statePath, 'utf8'));
const recorded = path.resolve(state.target && state.target.root || '');
const current = path.resolve(targetRoot);
if (recorded !== current) {
throw new Error(`Install-state recorded root ${recorded} != current ${current}; remove the state or move the project back.`);
}
}
assertStateRootMatches(plan.installStatePath, plan.targetRoot); Type guard
null
Try / catch
try {
await applyMultiHarnessPlan(plan);
} catch (err) {
if (/recorded root does not match the current install root/.test(err.message)) {
fs.rmSync(plan.installStatePath, { force: true });
const fresh = await createMultiHarnessPlan(plan.request);
await applyMultiHarnessPlan(fresh);
} else throw err;
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Refusing to trust managed install-state at ${plan.installSta
- Refusing to trust managed install-state at ${plan.installSta
- Refusing to trust non-managed ownership from install-state a
- Refusing unverified ownership from install-state at ${plan.i
- Refusing unverified ownership from install-state at ${plan.i
AI-assisted analysis of affaan-m/ECC@01e15490f0 (2026-08-13).
Data as JSON: /api/errors/cdae627986f8d40b.
Report an issue: GitHub.