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
- Open the install-state file and remove entries whose ownership is not 'managed', or restore the file from a known-good version.
- Regenerate the install-state by deleting it and re-running the guided install.
- 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
- Never hand-edit install-state files.
- Keep user-owned files out of install-state; track them elsewhere.
- Validate state schema after upgrading ECC versions.
- Restore state from a known-good copy rather than patching entries manually.
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
- A managed install-state path is required before preflight.
- application bundle differs from its bound evidence
- approval evidence must bind exact source, candidate and…
- artifact byte size does not match receipt
- artifact cites an unknown provenance source
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)