affaan-m/ECC · error · Error
Refusing unverified ownership from install-state at ${plan.i
Error message
Refusing unverified ownership from install-state at ${plan.installStatePath}: content digest does not match ${destinationPath}. What it means
Thrown by readOwnedDestinations after the identity check passes, when the destination file's current SHA-256 does not match the operation's recorded contentSha256. This is the cryptographic proof that ECC still owns the file: even if identity matches, if the bytes on disk differ from what ECC wrote (or the file is missing, or contentSha256 is malformed), ownership is no longer verifiable and the file is treated as user-modified. The regex /^[a-f0-9]{64}$/i also rejects malformed or missing digests.
Source
Thrown at scripts/lib/multi-harness-setup.js:178
}
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 || '')
|| currentFingerprint.sha256 !== operation.contentSha256.toLowerCase()
) {
throw new Error(
`Refusing unverified ownership from install-state at ${plan.installStatePath}: `
+ `content digest does not match ${destinationPath}.`
);
}
destinations.add(canonicalDestination);
}
return { destinations, stateFingerprint: validatedFingerprint };
}
function assertMergeDestination(destinationPath) {
if (!fs.existsSync(destinationPath)) return null;
let current;
try {
current = JSON.parse(fs.readFileSync(destinationPath, 'utf8'));
} catch (error) {
throw new Error(`Cannot merge ECC configuration into invalid JSON at ${destinationPath}: ${error.message}`);
}
if (!current || typeof current !== 'object' || Array.isArray(current)) {View on GitHub (pinned to 01e15490f0)
Solutions
- If you intentionally modified the file, remove the install-state and re-run the preview so ECC re-records ownership of the current bytes (or move your edits aside first).
- Restore the file to the exact bytes ECC wrote (e.g., git checkout the managed version) so the digest matches contentSha256.
- If contentSha256 in the state looks malformed, treat the state as corrupt: delete it and regenerate.
- Disable formatters/linters that rewrite ECC-managed files, or add them to the managed set explicitly.
Example fix
// before: user edited managed file, digest no longer matches state
// state op.contentSha256 = 'aa...'
// current file sha256 = 'bb...'
readOwnedDestinations(plan); // throws [288]
// after (option A): re-record ownership for the edited file
fs.rmSync(plan.installStatePath, { force: true });
const plan2 = await createMultiHarnessPlan(req);
await applyMultiHarnessPlan(plan2);
// after (option B): restore original bytes
fs.copyFileSync(originalManagedFile, destinationPath); Defensive patterns
Strategy: validation
Validate before calling
const fs = require('fs'); const crypto = require('crypto');
function assertDestinationsMatchDigests(statePath) {
if (!fs.existsSync(statePath)) return;
const state = JSON.parse(fs.readFileSync(statePath, 'utf8'));
for (const op of state.operations || []) {
if (!fs.existsSync(op.destinationPath)) {
throw new Error(`Managed file missing: ${op.destinationPath}`);
}
if (!/^[a-f0-9]{64}$/i.test(op.contentSha256 || '')) {
throw new Error(`Malformed contentSha256 for ${op.destinationPath}`);
}
const cur = crypto.createHash('sha256').update(fs.readFileSync(op.destinationPath)).digest('hex');
if (cur !== op.contentSha256.toLowerCase()) {
throw new Error(`Managed file modified externally: ${op.destinationPath}`);
}
}
}
assertDestinationsMatchDigests(plan.installStatePath); Type guard
null
Try / catch
try {
await applyMultiHarnessPlan(plan);
} catch (err) {
if (/content digest does not match/.test(err.message)) {
// decide: re-record ownership (delete state + re-preview) or restore the original bytes
fs.rmSync(plan.installStatePath, { force: true });
const fresh = await createMultiHarnessPlan(plan.request);
await applyMultiHarnessPlan(fresh);
} else throw err;
} Prevention
- Do not hand-edit ECC-managed files; if you must, delete the install-state and re-install.
- Disable formatters/linters that auto-rewrite managed config files.
- Normalize line endings project-wide so cross-platform checkout does not change digests.
- Treat unexpected digest drift as a signal the file was modified, not as an ECC bug.
When it happens
Trigger: Fires when fingerprintFile(destinationPath).exists is false, when operation.contentSha256 is not a valid 64-char hex digest, or when the current sha256 differs from contentSha256.toLowerCase(). Occurs when the user edited an ECC-managed file, another tool rewrote it (formatter, postinstall), the file was deleted, or the state's contentSha256 field was corrupted/uppercased/truncated.
Common situations: User hand-editing an ECC-managed config file; a linter/formatter rewriting a managed file on save; partial checkout where the file is missing; git line-ending normalization changing the digest; state corruption altering contentSha256; cross-platform EOL differences changing the hash.
Related errors
- Refusing to trust non-managed ownership from install-state a
- Refusing to trust managed install-state at ${plan.installSta
- Refusing to trust managed install-state at ${plan.installSta
- Refusing to trust managed install-state at ${plan.installSta
- 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/56d250e09cf8eb63.
Report an issue: GitHub.