{"record":{"id":"9dfd420e9309f511","repo":"astrid-runtime/astrid","slug":"legacy-distro-conflict-at-path-detail","errorCode":null,"errorMessage":"legacy distro conflict at {path}: {detail}","messagePattern":"legacy distro conflict at (.+?): (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-kernel/src/principal_distro_migration.rs","lineNumber":569,"sourceCode":"}\n\n#[cfg(not(unix))]\n// Windows publication is already write-through; keep the shared fallible\n// signature so migration call sites remain platform-independent.\n#[allow(clippy::unnecessary_wraps)]\nfn sync_parent(_path: &Path) -> io::Result<()> {\n    Ok(())\n}\n\nfn invalid(path: &Path, detail: &str) -> io::Error {\n    io::Error::new(\n        io::ErrorKind::InvalidData,\n        format!(\"legacy distro {}: {detail}\", path.display()),\n    )\n}\n\nfn conflict(path: &Path, detail: &str) -> io::Error {\n    io::Error::new(\n        io::ErrorKind::AlreadyExists,\n        format!(\"legacy distro conflict at {}: {detail}\", path.display()),\n    )\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    fn lock_text() -> &'static str {\n        \"schema-version = 1\\n\\n[distro]\\nid = \\\"example\\\"\\nversion = \\\"1.0.0\\\"\\nresolved-at = \\\"2026-01-01T00:00:00Z\\\"\\n\"\n    }\n\n    #[test]\n    fn source_snapshot_counts_only_the_private_lock() {\n        let directory = tempfile::tempdir().unwrap();\n        let home = AstridHome::from_path(directory.path().join(\"astrid\"));\n        let alias = PrincipalId::new(\"alice\").unwrap();","sourceCodeStart":551,"sourceCodeEnd":587,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-kernel/src/principal_distro_migration.rs#L551-L587","documentation":"This io::Error with ErrorKind::AlreadyExists signals a conflict during legacy distro migration: something the migration wants to create or retire already exists in an incompatible state at {path}. The {detail} describes the colliding artifact (e.g. an existing lock or destination).","triggerScenarios":"Calling conflict(path, detail) from retire_legacy_distro_init_locks, migrate_one, retire_source, read_digest, or read_bounded when an init lock, destination entry, or source already exists or is unexpectedly present.","commonSituations":"Re-running a partially completed migration, concurrent migration processes racing on the same distro, stale lock files left by a crashed prior run.","solutions":["Check whether a previous migration run partially completed and clean up stale locks at {path}","Ensure only one migration process runs at a time","Remove or rename the conflicting artifact once its state is understood","Re-run the migration, which should now proceed idempotently"],"exampleFix":"// before: hard failure on existing lock\nretire_legacy_distro_init_locks(path)?;\n// after: tolerate already-retired locks\nmatch retire_legacy_distro_init_locks(path) {\n    Ok(()) => {},\n    Err(e) if e.kind() == io::ErrorKind::AlreadyExists => log::info!(\"locks already retired\"),\n    Err(e) => return Err(e),\n}","handlingStrategy":"try-catch","validationCode":"if init_lock_path.exists() { cleanup_stale_lock(init_lock_path)?; }","typeGuard":"fn lock_is_stale(p: &Path, max_age: Duration) -> bool {\n    p.metadata().map(|m| m.modified().map(|t| t.elapsed().unwrap_or_default() > max_age).unwrap_or(true)).unwrap_or(false)\n}","tryCatchPattern":"match migrate_one(path) {\n    Err(e) if e.kind() == io::ErrorKind::AlreadyExists => cleanup_and_retry(path)?,\n    Err(e) => return Err(e),\n    Ok(()) => {},\n}","preventionTips":["Use an external process lock so only one migration runs at a time","Clean stale init locks after crashed runs","Make migration idempotent so re-runs tolerate existing artifacts"],"tags":["filesystem","migration","conflict","already-exists"],"backgroundTag":"file-already-exists","analyzedSha":"affd8760f44190dbdfbec23403f4c4b642c33112","analyzedAt":"2026-09-09T21:28:12.402Z","contentChangedAt":"2026-09-09T21:28:12.402Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}