{"record":{"id":"30ee878e7bdd6e21","repo":"astrid-runtime/astrid","slug":"invalid-logical-destination-destination-error","errorCode":null,"errorMessage":"invalid logical destination {destination}: {error}","messagePattern":"invalid logical destination (.+?): (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-kernel/src/principal_home_migration/mod.rs","lineNumber":603,"sourceCode":"            bytes: self.bytes,\n        }\n    }\n}\n\nfn preflight_entry(\n    filesystem: &AstridFilesystem<\n        StateOwner,\n        astrid_storage::engine::DurableEngine<\n            StateOwner,\n            astrid_storage::Blake3ObjectIdentityV1,\n            astrid_storage::StateOwnerCodecV2,\n        >,\n    >,\n    source_root: &Path,\n    entry: &MigrationEntry,\n) -> io::Result<()> {\n    let destination = FilesystemPath::new(entry.destination.clone()).map_err(|error| {\n        io::Error::new(\n            io::ErrorKind::InvalidData,\n            format!(\"invalid logical destination {}: {error}\", entry.destination),\n        )\n    })?;\n    match entry.kind {\n        EntryKind::Directory => match filesystem.stat(&destination) {\n            Ok(existing) if existing.kind() == FilesystemEntryKind::Directory => {},\n            Ok(_) => {\n                return Err(conflict_fs(\n                    &destination,\n                    \"destination kind conflicts with source directory\",\n                ));\n            },\n            Err(FilesystemError::NotFound(_)) => {},\n            Err(error) => return Err(storage_error(&error)),\n        },\n        EntryKind::File => match filesystem.stat(&destination) {\n            Ok(existing) if existing.kind() == FilesystemEntryKind::File => {","sourceCodeStart":585,"sourceCodeEnd":621,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-kernel/src/principal_home_migration/mod.rs#L585-L621","documentation":"Raised by preflight_entry when the entry.destination string from a migration entry cannot be converted into a valid logical FilesystemPath. The underlying FilesystemPath parse error is embedded. Preflight aborts before any filesystem mutation.","triggerScenarios":"Calling migrate_one_principal -> preflight_entry with a MigrationEntry whose destination field is malformed (empty string, illegal components, path traversal, invalid logical path syntax).","commonSituations":"Corrupted or hand-edited migration receipt files, destinations produced by an older buggy writer, or receipts copied between systems with different path conventions.","solutions":["Check the {destination} value in the receipt for syntax problems (empty, '..', absolute/relative mix)","Regenerate the migration receipt from a trustworthy source","Repair the receipt's destination field to a valid logical path","Restore receipts from backup if they were corrupted"],"exampleFix":"// before: corrupt destination string in receipt\n\"destination\": \"uploads//../../etc\"\n// after: sanitized logical destination\n\"destination\": \"uploads/principal-a/file.bin\"","handlingStrategy":"validation","validationCode":"fn destination_is_valid(dest: &str) -> bool {\n    !dest.is_empty() && FilesystemPath::new(dest.to_string()).is_ok()\n}","typeGuard":"fn parse_logical_path(s: &str) -> Option<FilesystemPath> { FilesystemPath::new(s.to_string()).ok() }","tryCatchPattern":"match preflight_result {\n    Err(e) if e.kind() == io::ErrorKind::InvalidData => report_bad_receipt_entry(e),\n    Err(e) => return Err(e),\n    Ok(()) => proceed(),\n}","preventionTips":["Never hand-edit receipt destination fields","Validate all receipt entries with FilesystemPath::new before running migration","Use only relative, '/'-separated logical components when generating receipts"],"tags":["validation","paths","migration"],"backgroundTag":"invalid-url-format","analyzedSha":"affd8760f44190dbdfbec23403f4c4b642c33112","analyzedAt":"2026-09-09T21:28:12.402Z","contentChangedAt":"2026-09-09T21:28:12.402Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}