astrid-runtime/astrid · error · io::Error
quarantine to
Error message
quarantine {} to {}: {error} What it means
When a legacy audit source cannot be migrated in place, quarantine_audit_tree moves the whole tree into the migrations quarantine directory via fs::rename. If the rename fails for any reason, the original OS error is wrapped with this contextual message showing source and destination.
Solutions
- Ensure the legacy source and the astrid migrations directory are on the same filesystem, or copy-then-delete instead of rename
- Fix permissions on the quarantine root (ensure_private_directory should have created it; check ownership)
- Check the wrapped underlying error kind in the message and address it directly (e.g. free disk space, remount rw)
- Retry after stopping whatever process holds/removes the source tree
Example fix
// before: rename fails across filesystems
fs::rename(source, &destination).map_err(...)?;
// after: fall back to copy+remove on cross-device errors
if let Err(error) = fs::rename(source, &destination) {
if error.kind() == io::ErrorKind::CrossesDevices {
copy_tree(source, &destination)?;
fs::remove_dir_all(source)?;
} else { return Err(wrap(error, source, &destination)); }
} Defensive patterns
Strategy: try-catch
Validate before calling
let quarantine_root = home.migrations_dir().join(QUARANTINE_DIR); astrid_core::platform_fs::ensure_private_directory(&quarantine_root)?; // same-device check to avoid EXDEV dev_of(source)? == dev_of(&quarantine_root)?
Try / catch
match quarantine_audit_tree(&home, &alias, &source) {
Err(e) if e.kind() == std::io::ErrorKind::CrossesDevices => copy_then_remove(&source)?,
Err(e) if e.kind() == std::io::ErrorKind::PermissionDenied => fix_perms_and_retry()? ,
other => other,
} Prevention
- Keep the legacy audit tree and astrid home on the same filesystem
- Ensure the migrations directory is writable by the migration user
- Handle EXDEV by copying then removing when rename cannot work
When it happens
Trigger: handle_non_default_audit_source calls quarantine_audit_tree; fs::rename(source, destination) fails — e.g. source and destination on different filesystems (EXDEV), destination collision beyond unique_destination's attempts, or permission problems.
Common situations: The legacy audit tree lives on a different mount than the astrid home (rename across devices); read-only filesystem; the migrations directory is not writable; the source was concurrently removed.
Understand the failure class
Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.
Related errors
- capability-relative exclusive rename is unsupported
- exhausted unique names for quarantined leftover capsule…
- InvalidData
- InvalidData
- InvalidInput
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/37ddaff20104d770.
Report an issue: GitHub.
Appendix: source
Thrown at crates/astrid-kernel/src/legacy_migration_barrier/legacy_audit.rs:55
}
if !path_exists(&path)? {
return Err(io::Error::new(
io::ErrorKind::InvalidData,
format!(
"legacy audit source for {alias} was inventoried but is missing: {}",
path.display()
),
));
}
quarantine_audit_tree(home, alias, &path)
}
fn quarantine_audit_tree(home: &AstridHome, alias: &PrincipalId, source: &Path) -> io::Result<()> {
let quarantine_root = home.migrations_dir().join(QUARANTINE_DIR);
astrid_core::platform_fs::ensure_private_directory(&quarantine_root)?;
let destination = unique_destination(&quarantine_root, alias.as_str())?;
fs::rename(source, &destination).map_err(|error| {
io::Error::new(
error.kind(),
format!(
"quarantine {} to {}: {error}",
source.display(),
destination.display()
),
)
})?;
super::sync_parent(source)?;
super::sync_parent(&destination)?;
tracing::warn!(
principal = %alias,
destination = %destination.display(),
"quarantined non-default layout-1 audit tree; bytes preserved"
);
Ok(())
}
View on GitHub (pinned to affd8760f4)