astrid-runtime/astrid · error
invalid logical destination
Error message
invalid logical destination {destination}: {error} What it means
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.
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
Example fix
// before: corrupt destination string in receipt "destination": "uploads//../../etc" // after: sanitized logical destination "destination": "uploads/principal-a/file.bin"
Defensive patterns
Strategy: validation
Validate before calling
fn destination_is_valid(dest: &str) -> bool {
!dest.is_empty() && FilesystemPath::new(dest.to_string()).is_ok()
} Type guard
fn parse_logical_path(s: &str) -> Option<FilesystemPath> { FilesystemPath::new(s.to_string()).ok() } Try / catch
match preflight_result {
Err(e) if e.kind() == io::ErrorKind::InvalidData => report_bad_receipt_entry(e),
Err(e) => return Err(e),
Ok(()) => proceed(),
} Prevention
- 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
When it happens
Trigger: Calling migrate_one_principal -> preflight_entry with a MigrationEntry whose destination field is malformed (empty string, illegal components, path traversal, invalid logical path syntax).
Common situations: Corrupted or hand-edited migration receipt files, destinations produced by an older buggy writer, or receipts copied between systems with different path conventions.
Understand the failure class
Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.
Related errors
- invalid destination parent
- invalid receipt destination
- absent migration source has a digest
- cannot migrate an Astrid home without a layout-version…
- destination proof is missing its payload
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/30ee878e7bdd6e21.
Report an issue: GitHub.
Appendix: source
Thrown at crates/astrid-kernel/src/principal_home_migration/mod.rs:603
bytes: self.bytes,
}
}
}
fn preflight_entry(
filesystem: &AstridFilesystem<
StateOwner,
astrid_storage::engine::DurableEngine<
StateOwner,
astrid_storage::Blake3ObjectIdentityV1,
astrid_storage::StateOwnerCodecV2,
>,
>,
source_root: &Path,
entry: &MigrationEntry,
) -> io::Result<()> {
let destination = FilesystemPath::new(entry.destination.clone()).map_err(|error| {
io::Error::new(
io::ErrorKind::InvalidData,
format!("invalid logical destination {}: {error}", entry.destination),
)
})?;
match entry.kind {
EntryKind::Directory => match filesystem.stat(&destination) {
Ok(existing) if existing.kind() == FilesystemEntryKind::Directory => {},
Ok(_) => {
return Err(conflict_fs(
&destination,
"destination kind conflicts with source directory",
));
},
Err(FilesystemError::NotFound(_)) => {},
Err(error) => return Err(storage_error(&error)),
},
EntryKind::File => match filesystem.stat(&destination) {
Ok(existing) if existing.kind() == FilesystemEntryKind::File => {View on GitHub (pinned to affd8760f4)