{"record":{"id":"56d250e09cf8eb63","repo":"affaan-m/ECC","slug":"refusing-unverified-ownership-from-install-state-a-56d250","errorCode":null,"errorMessage":"Refusing unverified ownership from install-state at ${plan.installStatePath}: content digest does not match ${destinationPath}.","messagePattern":"Refusing unverified ownership from install-state at (.+?): content digest does not match (.+?)\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/lib/multi-harness-setup.js","lineNumber":227,"sourceCode":"    }\n    const destinationPath = operation.destinationPath;\n    assertWithinTrustedRoot(destinationPath, plan.targetRoot, 'trust install-state ownership');\n    const canonicalDestination = canonicalPath(destinationPath);\n    const plannedOperation = plannedByDestination.get(canonicalDestination);\n    if (!plannedOperation) continue;\n    if (!operationIdentityMatches(operation, plannedOperation)) {\n      throw new Error(\n        `Refusing unverified ownership from install-state at ${plan.installStatePath}: `\n        + `operation identity does not match the current plan for ${destinationPath}.`\n      );\n    }\n    const currentFingerprint = fingerprintFile(destinationPath);\n    if (\n      !currentFingerprint.exists\n      || !/^[a-f0-9]{64}$/i.test(operation.contentSha256 || '')\n      || currentFingerprint.sha256 !== operation.contentSha256.toLowerCase()\n    ) {\n      throw new Error(\n        `Refusing unverified ownership from install-state at ${plan.installStatePath}: `\n        + `content digest does not match ${destinationPath}.`\n      );\n    }\n    destinations.add(canonicalDestination);\n  }\n  return { destinations, stateFingerprint: validatedFingerprint };\n}\n\nfunction assertMergeDestination(destinationPath, existingSnapshot = null) {\n  const snapshot = existingSnapshot || readRegularFileSnapshot(destinationPath);\n  if (!snapshot) return null;\n  let current;\n  try {\n    current = JSON.parse(snapshot.content.toString('utf8'));\n  } catch (error) {\n    throw new Error(`Cannot merge ECC configuration into invalid JSON at ${destinationPath}: ${error.message}`);\n  }","sourceCodeStart":209,"sourceCodeEnd":245,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/scripts/lib/multi-harness-setup.js#L209-L245","documentation":"To accept a state-recorded operation as owned, the current on-disk file's sha256 must exist and exactly match the contentSha256 recorded in install-state (which must itself be a valid 64-hex digest). If the file is missing, its digest is absent/malformed, or it differs, this error is thrown — the file was modified, replaced, or deleted since the install, so blindly treating it as ECC-owned would destroy user changes.","triggerScenarios":"The destination file was edited by the user or another tool after install; the file was deleted; operation.contentSha256 is missing or not a 64-char hex string; newline/encoding conversion (e.g. git autocrlf) changed file bytes.","commonSituations":"User customized an ECC-managed file locally; a formatter or line-ending setting rewrote the file; git checkout normalized line endings changing the hash; partial/failed install left a file without a recorded digest.","solutions":["Re-run the guided install/preview to rebuild install-state fingerprints against the current files.","If you intentionally modified the file, back up your changes, let the install refresh it, then reapply your edits (or move customizations to a non-managed file).","Check git/editor line-ending settings (core.autocrlf) that alter managed files and invalidate hashes; normalize and regenerate state."],"exampleFix":"// before: user-edited managed file keeps stale hash\n// after: refresh state for current files\nfs.rmSync(plan.installStatePath);\nconst plan = buildPlan(adapter); // preview shows the file will be overwritten","handlingStrategy":"validation","validationCode":"const crypto = require('crypto');\nconst actual = crypto.createHash('sha256').update(fs.readFileSync(dest)).digest('hex');\nif (actual !== recorded.contentSha256) throw new Error(`${dest} changed since install; refresh install-state or reapply your edits after update.`);","typeGuard":"function digestIsValidAndCurrent(recorded, dest) {\n  return /^[a-f0-9]{64}$/i.test(recorded?.contentSha256 || '')\n    && crypto.createHash('sha256').update(fs.readFileSync(dest)).digest('hex') === recorded.contentSha256.toLowerCase();\n}","tryCatchPattern":"try {\n  readOwnedDestinations(plan, deps);\n} catch (err) {\n  if (String(err.message).includes('content digest does not match')) {\n    // file changed since install: back up user edits, re-run guided install\n    console.error('A managed file changed since install; run the guided install to refresh.');\n  } else throw err;\n}","preventionTips":["Treat ECC-managed files as generated: keep customizations in separate files.","Set git attributes (e.g. * -text for managed files) to prevent line-ending rewrites changing hashes.","Re-run the guided install after manually touching any managed file.","Never edit managed files in place; diff and merge through the install flow."],"tags":["checksum-mismatch","install-state","file-integrity"],"backgroundTag":"checksum-mismatch","analyzedSha":"8321021c54d670126ce3b2969d5deb880b4b0c2a","analyzedAt":"2026-09-16T10:08:13.343Z","contentChangedAt":"2026-09-16T10:08:13.343Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}