affaan-m/ECC · error · Error

Refusing to trust non-managed ownership from install-state…

Error message

Refusing to trust non-managed ownership from install-state at ${plan.installStatePath}.

What it means

Every operation recorded in the install-state file must have ownership === 'managed'; readOwnedDestinations throws this error the moment it encounters a state operation with any other ownership value. Non-managed entries are user-owned files the library never claimed, so trusting them as owned destinations would allow overwriting user content.

Solutions

  1. Open the install-state file and remove entries whose ownership is not 'managed', or restore the file from a known-good version.
  2. Regenerate the install-state by deleting it and re-running the guided install.
  3. Do not hand-add custom files to install-state; track user-owned files outside this state file.

Example fix

// before (state.operations entry)
{ "destinationPath": "/repo/my-file", "ownership": "user" }
// after
{ "destinationPath": "/repo/my-file", "ownership": "managed" } // only if truly ECC-managed; otherwise delete the entry
Defensive patterns

Strategy: validation

Validate before calling

const state = JSON.parse(fs.readFileSync(plan.installStatePath, 'utf8'));
const bad = (state.operations || []).filter(op => op.ownership !== 'managed');
if (bad.length) throw new Error(`Non-managed entries in install-state: ${bad.map(o => o.destinationPath).join(', ')}`);

Type guard

function allManaged(state) {
  return (state?.operations || []).every(op => op.ownership === 'managed');
}

Try / catch

try {
  readOwnedDestinations(plan, deps);
} catch (err) {
  if (String(err.message).includes('non-managed ownership')) {
    fs.rmSync(plan.installStatePath); // regenerate state via guided install
  } else throw err;
}

Prevention

When it happens

Trigger: state.operations contains an entry with a missing or non-'managed' ownership field while iterating state.operations in readOwnedDestinations — typically from a hand-edited, older-format, or corrupted install-state file.

Common situations: User manually edited the install-state JSON to add their own files; a state file from an older schema version lacking the ownership field; a corrupted or truncated state write.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16). Data as JSON: /api/errors/8302a1e8967c532e. Report an issue: GitHub.

Appendix: source

Thrown at scripts/lib/multi-harness-setup.js:206

  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 => [
    canonicalPath(operation.destinationPath),
    operation,
  ]));
  const destinations = new Set();
  for (const operation of state.operations || []) {
    if (operation.ownership !== 'managed') {
      throw new Error(
        `Refusing to trust non-managed ownership from install-state at ${plan.installStatePath}.`
      );
    }
    const destinationPath = operation.destinationPath;
    assertWithinTrustedRoot(destinationPath, plan.targetRoot, 'trust install-state ownership');
    const canonicalDestination = canonicalPath(destinationPath);
    const plannedOperation = plannedByDestination.get(canonicalDestination);
    if (!plannedOperation) continue;
    if (!operationIdentityMatches(operation, plannedOperation)) {
      throw new Error(
        `Refusing unverified ownership from install-state at ${plan.installStatePath}: `
        + `operation identity does not match the current plan for ${destinationPath}.`
      );
    }
    const currentFingerprint = fingerprintFile(destinationPath);
    if (
      !currentFingerprint.exists
      || !/^[a-f0-9]{64}$/i.test(operation.contentSha256 || '')

View on GitHub (pinned to 8321021c54)