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

  1. Inspect the wrapped error.message to see which safety check failed (root containment, traversal, symlink).
  2. Set plan.installStatePath inside plan.targetRoot and remove traversal segments or symlinks from the path.
  3. 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

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


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)