{"record":{"id":"2a6e1cd684bd4bbe","repo":"affaan-m/ECC","slug":"refusing-to-replace-modified-legacy-codex-artifact","errorCode":null,"errorMessage":"Refusing to replace modified legacy Codex artifact: ${filePath}","messagePattern":"Refusing to replace modified legacy Codex artifact: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/lib/codex-legacy-sync.js","lineNumber":212,"sourceCode":"  return {\n    path: filePath,\n    installedSha256: null,\n    previousType,\n    previousContentBase64: snapshot ? snapshot.content.toString('base64') : null,\n    previousMode: snapshot ? snapshot.mode : null,\n  };\n}\n\nfunction assertInstalledStateUnmodified(state) {\n  for (const entry of state.paths) {\n    const filePath = path.resolve(entry.path);\n    const trustedRoot = getTrustedRoot(state, filePath);\n    if (!trustedRoot || hasUnsafeManagedAncestor(filePath, trustedRoot)) {\n      throw new Error(`Refusing to reuse unsafe legacy Codex ownership path: ${filePath}`);\n    }\n    const snapshot = readRegularFileNoFollow(filePath);\n    if (!entry.installedSha256) {\n      if (snapshot) throw new Error(`Refusing to replace modified legacy Codex artifact: ${filePath}`);\n      continue;\n    }\n    const digest = snapshot\n      ? crypto.createHash('sha256').update(snapshot.content).digest('hex')\n      : null;\n    if (digest !== entry.installedSha256) {\n      throw new Error(`Refusing to replace modified legacy Codex artifact: ${filePath}`);\n    }\n  }\n}\n\nfunction beginLegacySyncState(options) {\n  const codexHome = path.resolve(options.codexHome);\n  const statePath = getStatePath(codexHome);\n  const configPath = path.join(codexHome, 'config.toml');\n  const agentsPath = path.join(codexHome, 'AGENTS.md');\n  const installedHooksPath = options.installedHooksPath ? path.resolve(options.installedHooksPath) : null;\n  const priorState = readStateIfPresent(statePath);","sourceCodeStart":194,"sourceCodeEnd":230,"githubUrl":"https://github.com/affaan-m/ECC/blob/06c5e118c4d3e6c3b7f9445f973a2194c82de193/scripts/lib/codex-legacy-sync.js#L194-L230","documentation":"While verifying prior install state, assertInstalledStateUnmodified() hits an entry whose installedSha256 is null — the path was recorded as absent (a tombstone for a file ECC intended to create) — but readRegularFileNoFollow() now finds a regular file there. Because ECC never wrote that file, overwriting it could destroy user data, so the reinstall is refused.","triggerScenarios":"A first sync recorded paths it planned to create and was interrupted before installing them; before the retry, someone (user, other tool, other agent) created a file at one of those paths, e.g. ~/.codex/config.toml now exists where the entry expected absence.","commonSituations":"User runs 'codex' login/config between a failed ECC install and the retry; dotfile managers or parallel agents writing into CODEX_HOME concurrently.","solutions":["Inspect the file named in the error; if it is disposable or yours, move it aside and re-run the sync","If it must be kept, copy its content elsewhere, let ECC manage the path, then merge manually","If the whole install state is stale, back up and delete the sync-state file to start fresh"],"exampleFix":"# before: retry throws Refusing to replace modified legacy Codex artifact: /home/u/.codex/config.toml\nmv ~/.codex/config.toml ~/.codex/config.toml.pre-ecc\n# after: re-run the legacy Codex sync, then merge your config back if needed","handlingStrategy":"validation","validationCode":"const fs = require('fs'), path = require('path');\nconst conflicts = state.paths\n  .filter(e => !e.installedSha256)\n  .filter(e => fs.existsSync(path.resolve(e.path)));\nif (conflicts.length) reportFileConflicts(conflicts); // resolve before re-running the sync","typeGuard":null,"tryCatchPattern":"try { beginLegacySyncState({ codexHome }); }\ncatch (err) {\n  if (/Refusing to replace modified legacy Codex artifact/.test(err.message)) {\n    // the message contains the path: move the unexpected file aside, then retry\n  } else throw err;\n}","preventionTips":["Do not create files in CODEX_HOME while a sync is pending","Complete or roll back interrupted installs before letting other tooling run","Treat paths in the state file as reserved by ECC"],"tags":["codex","file-conflict","install","integrity"],"backgroundTag":"file-conflict-on-install","analyzedSha":"06c5e118c4d3e6c3b7f9445f973a2194c82de193","analyzedAt":"2026-08-18T11:27:13.915Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}