affaan-m/ECC · error · Error
Refusing to trust managed install-state path
Error message
Refusing to trust managed install-state path: ${error.message} What it means
Before reading an install-state file, readOwnedDestinations runs assertSafeInstallOperation against the state path itself. If that safety check rejects the path (e.g. outside the trusted root, unsafe path shape, or a symlink/traversal risk), the original failure is rethrown wrapped as 'Refusing to trust managed install-state path'. The install-state location itself must be a safe, managed destination before its contents can be trusted.
Solutions
- Inspect the wrapped error.message to see which safety check failed (root containment, traversal, symlink).
- Set plan.installStatePath inside plan.targetRoot and remove traversal segments or symlinks from the path.
- If the state path was customized, revert to the adapter's default install-state location and re-run the install.
Example fix
// before
const plan = buildPlan({ targetRoot: '/repo', installStatePath: '/shared/state.json' });
// after
const plan = buildPlan({ targetRoot: '/repo' }); // state kept inside the trusted root Defensive patterns
Strategy: validation
Validate before calling
const resolved = path.resolve(plan.installStatePath);
if (!resolved.startsWith(path.resolve(plan.targetRoot) + path.sep)) {
throw new Error('installStatePath must live inside targetRoot');
} Type guard
function isSafeStatePath(p, root) {
const resolved = path.resolve(p);
return resolved.startsWith(path.resolve(root) + path.sep) && !p.includes('..');
} Try / catch
try {
readOwnedDestinations(plan, deps);
} catch (err) {
if (String(err.message).startsWith('Refusing to trust managed install-state path:')) {
console.error('Fix installStatePath (inside targetRoot, no symlinks/traversal):', err.message);
} else throw err;
} Prevention
- Keep installStatePath inside the target root and free of symlinks.
- Never accept install-state paths from untrusted input.
- Use the adapter's default state path.
- Run assertSafeInstallOperation yourself in tests for custom path configurations.
When it happens
Trigger: plan.installStatePath points outside the trusted target root, contains path-traversal segments, resolves through a symlink, or otherwise fails assertSafeInstallOperation; readOwnedDestinations is called via the ownership step of install/update.
Common situations: Custom installStatePath configured to a shared/home directory outside the target root; misconfigured adapter; state path pointing at a symlinked dotfile; attacker-influenced or hand-edited plan paths.
Understand the failure class
Background: Path traversal blocked: "path escapes the workspace" and "outside site root" errors when a path will not stay inside its allowed directory — this error's family across 26 libraries.
Related errors
- A managed install-state path is required before preflight.
- Invalid install-state
- Refusing to : missing destination path.
- Refusing to apply install operation: missing destination…
- Refusing to trust managed install-state at
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/597fe95c8b704892.
Report an issue: GitHub.
Appendix: source
Thrown at scripts/lib/multi-harness-setup.js:181
+ '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 });
} catch (error) {
throw new Error(`Refusing to trust managed install-state path: ${error.message}`);
}
const initialFingerprint = fingerprintFile(plan.installStatePath);
if (!initialFingerprint.exists) {
return { destinations: new Set(), stateFingerprint: { exists: false, sha256: null } };
}
const readState = dependencies.readInstallState || require('./install-state').readInstallState;
const state = readState(plan.installStatePath);
const validatedFingerprint = fingerprintFile(plan.installStatePath);
if (
initialFingerprint.exists !== validatedFingerprint.exists
|| initialFingerprint.sha256 !== validatedFingerprint.sha256
) {
throw new Error(
`Refusing to trust install-state that changed during validation: ${plan.installStatePath}.`
);
}
assertPriorInstallStateMatchesPlan(state, plan);
const plannedByDestination = new Map(plan.operations.map(operation => [View on GitHub (pinned to 8321021c54)