{"record":{"id":"ecb5d26e2bd94904","repo":"affaan-m/ECC","slug":"legacy-codex-sync-state-not-found-at-statepath","errorCode":null,"errorMessage":"Legacy Codex sync state not found at ${statePath}","messagePattern":"Legacy Codex sync state not found at (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/lib/codex-legacy-sync.js","lineNumber":140,"sourceCode":"        `Legacy sync path changed before removal; preserved replacement at ${quarantinePath}`\n      );\n    }\n    throw new Error(`Legacy sync path changed before removal: ${filePath}`);\n  }\n  fs.unlinkSync(quarantinePath);\n  fs.rmdirSync(quarantineDir);\n}\n\nfunction atomicWriteJson(filePath, value) {\n  fs.mkdirSync(path.dirname(filePath), { recursive: true, mode: 0o700 });\n  const tempPath = `${filePath}.tmp-${process.pid}-${Date.now()}`;\n  fs.writeFileSync(tempPath, `${JSON.stringify(value, null, 2)}\\n`, { mode: 0o600 });\n  fs.renameSync(tempPath, filePath);\n}\n\nfunction readState(statePath) {\n  const snapshot = readRegularFileNoFollow(statePath, 'utf8');\n  if (!snapshot) throw new Error(`Legacy Codex sync state not found at ${statePath}`);\n  return parseState(snapshot.content, statePath);\n}\n\nfunction readStateIfPresent(statePath) {\n  const snapshot = readRegularFileNoFollow(statePath, 'utf8');\n  return snapshot ? parseState(snapshot.content, statePath) : null;\n}\n\nfunction parseState(content, statePath) {\n  const state = JSON.parse(content);\n  if (state.schema !== SCHEMA || !Array.isArray(state.paths)) {\n    throw new Error(`Invalid legacy Codex sync state at ${statePath}`);\n  }\n  return state;\n}\n\nfunction hasUnsafeManagedAncestor(filePath, codexHome) {\n  const relativePath = path.relative(codexHome, filePath);","sourceCodeStart":122,"sourceCodeEnd":158,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/scripts/lib/codex-legacy-sync.js#L122-L158","documentation":"readState loads the legacy Codex sync state file (a JSON snapshot of files the installer manages) via a symlink-safe read. When the state file does not exist at statePath, it throws instead of returning null — unlike its sibling readStateIfPresent, which returns null for a missing file. This is an intentional hard failure: callers using readState expect an install to already be registered.","triggerScenarios":"Calling readState(statePath) (directly or through the exported state accessor) when no legacy sync state file exists at statePath — e.g. before the first beginLegacySyncState was ever run, after the state file was manually deleted, or when pointing at the wrong codexHome / wrong state path.","commonSituations":"Running an update/rollback command that expects a prior install on a machine where the plugin was never installed; a state file removed by a cleanup script or manual `rm`; CI runners with a fresh home directory; typo'd CODEX_HOME environment variable resolving to a different directory.","solutions":["Run the install/registration step (beginLegacySyncState) first so the state file is created before reading it.","If a missing state is a legitimate case, switch the caller to readStateIfPresent(statePath), which returns null instead of throwing.","Verify statePath/codexHome is correct (echo $CODEX_HOME, check the resolved path) — a typo'd path looks identical to a missing install.","If the state file was deleted but files exist, reinstall to regenerate a valid state snapshot rather than hand-crafting the JSON."],"exampleFix":"// before\nconst state = readState(statePath); // throws if never installed\n// after\nconst state = readStateIfPresent(statePath);\nif (!state) {\n  // fresh machine: run install flow instead\n  beginLegacySyncState({ codexHome });\n  return;\n}","handlingStrategy":"fallback","validationCode":"import fs from 'node:fs';\nif (!fs.existsSync(statePath)) {\n  // treat as fresh install instead of calling readState\n}","typeGuard":null,"tryCatchPattern":"let state;\ntry {\n  state = readState(statePath);\n} catch (err) {\n  if (err instanceof Error && err.message.startsWith('Legacy Codex sync state not found')) {\n    state = null; // fresh machine: run install flow\n  } else {\n    throw err;\n  }\n}","preventionTips":["Use readStateIfPresent when a missing state is an expected, recoverable case.","Always run beginLegacySyncState before any command that assumes an existing install.","Do not manually delete the sync state file; use the plugin's uninstall/cleanup flow.","Pin CODEX_HOME explicitly in scripts/CI so reads target the same directory the install wrote to."],"tags":["file-not-found","state-management","codex","installer"],"backgroundTag":"file-not-found","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"}