astrid-runtime/astrid · error
invalid receipt destination
Error message
invalid receipt destination {destination}: {error} What it means
Raised by verify_destinations when a receipt entry's destination cannot be parsed as a FilesystemPath during post-migration verification. Verification reads back all receipt pages and revalidates each destination; a parse failure aborts verification with InvalidData.
Solutions
- Validate receipt files before verification and repair or drop invalid entries
- Restore receipts from backup if corrupted
- Regenerate the migration by clearing receipts and re-running migration
- Check the writer version that produced the receipts for a format bug
Example fix
// before: verifying corrupt receipts aborts verify_destinations(&filesystem, &receipts, &summary)?; // after: pre-validate receipts let receipts = load_and_validate_receipts(&receipts_dir)?; verify_destinations(&filesystem, &receipts, &summary)?;
Defensive patterns
Strategy: validation
Validate before calling
fn receipts_parse(dir: &Path) -> bool {
load_receipt_pages(dir).map(|pages| pages.iter().all(|p| p.entries.iter().all(|e| FilesystemPath::new(e.destination.clone()).is_ok()))).unwrap_or(false)
} Type guard
fn valid_receipt_entry(e: &Entry) -> bool { FilesystemPath::new(e.destination.clone()).is_ok() } Try / catch
match verify_destinations(&fs, &receipts, &summary) {
Err(e) if e.kind() == io::ErrorKind::InvalidData => restore_receipts_from_backup()?,
Err(e) => return Err(e),
Ok(()) => {},
} Prevention
- Back up receipt files before verification
- Detect partial writes by checksumming receipt files
- Validate receipts immediately after migration, before cleanup
When it happens
Trigger: Calling migrate_one_principal -> verify_destinations when a stored receipt entry has a destination string FilesystemPath::new rejects — the same class of malformed logical path as [1505] but discovered at verification time.
Common situations: Receipt files corrupted on disk or partially written by a crashed run, receipts written by an incompatible older version, manual editing of receipt JSON.
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 logical 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/672c9533ee628774.
Report an issue: GitHub.
Appendix: source
Thrown at crates/astrid-kernel/src/principal_home_migration/mod.rs:741
) -> io::Result<()> {
let filesystem = AstridFilesystem::new(store.content(), StateOwner::Principal(uid));
let mut summary = InventorySummary::default();
let mut count = 0_u64;
for page_number in 0..receipt.page_count.get() {
let page = read_page(home, uid, page_number)?;
if page.page != page_number {
return Err(conflict_path(
&receipt_path_for_display(uid),
"receipt page sequence is not canonical",
));
}
for entry in page.entries {
summary.update(&entry)?;
count = count
.checked_add(1)
.ok_or_else(|| io::Error::other("receipt entry count overflow"))?;
let destination = FilesystemPath::new(entry.destination.clone()).map_err(|error| {
io::Error::new(
io::ErrorKind::InvalidData,
format!("invalid receipt destination {}: {error}", entry.destination),
)
})?;
match entry.kind {
EntryKind::Directory => {
let actual = filesystem
.stat(&destination)
.map_err(|error| storage_error(&error))?;
if actual.kind() != FilesystemEntryKind::Directory {
return Err(conflict_fs(
&destination,
"receipt destination is not a directory",
));
}
},
EntryKind::File => verify_file_content(&filesystem, &destination, &entry)?,
}View on GitHub (pinned to affd8760f4)