unicity-aos/aos-ce · error · io::Error
failed to validate ephemeral state exclusion
Error message
failed to validate ephemeral state exclusion: {error} What it means
`migrate_runtime` calls `ensure_no_ephemeral_data` on the staged runtime and wraps failures as "failed to validate ephemeral state exclusion". This check guarantees no ephemeral data (caches, sockets, tmp state) was copied into the staging tree; a failure here means the validation walk itself errored, so the migration aborts rather than importing potentially dirty state.
Solutions
- Inspect the wrapped inner error to identify which staged path failed, then fix that entry (permissions, broken symlink) and retry.
- Re-run the migration to rebuild the staging tree if the failure was transient (e.g. network filesystem hiccup).
- Exclude ephemeral/cache directories from the source before import so the staged tree is clean and scannable.
- Stage on a reliable local filesystem rather than a network mount to avoid traversal errors.
Defensive patterns
Strategy: try-catch
Validate before calling
scan_tree(&staging, |p| fs::metadata(p).map(|_| ()).map_err(|e| e.to_string()))?;
Try / catch
if let Some(io_err) = err.downcast_ref::<io::Error>() {
if let Some(inner) = io_err.to_string().strip_prefix("failed to validate ephemeral state exclusion: ") {
eprintln!("ephemeral scan failed at: {inner}");
}
} Prevention
- Stage migrations on a healthy local filesystem, not network mounts.
- Exclude ephemeral/cache directories from the import source beforehand.
- Retry the migration once on transient filesystem errors.
When it happens
Trigger: An I/O error raised by `ensure_no_ephemeral_data` while scanning the staged tree during `migrate_runtime` — e.g. unreadable staged directories, symlink loops, or vanished files mid-scan.
Common situations: Staging on a filesystem that errors on traversal (failing disk, network mount flaps), or an import source containing exotic entries (broken symlinks, permission-denied subdirs) that break the ephemeral-state scan.
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
- AOS managed path must be a real directory
- standalone runtime has no existing system lock; refusing an…
- failed to preserve imported activation state
- failed to inspect imported distro locks
- staged runtime did not validate against its import manifest
AI-assisted analysis of unicity-aos/aos-ce@f6f22024fb (2026-09-13).
Data as JSON: /api/errors/16e7872b5726a46f.
Report an issue: GitHub.
Appendix: source
Thrown at crates/unicity-aos-bootstrap/src/migration.rs:278
let mut entries = Vec::new();
copy_etc_state(&source, &staging, &mut entries)?;
for name in PERSISTENT_TOP_LEVEL {
copy_if_present(
&source.join(name),
&staging.join(name),
Path::new(name),
&mut entries,
)?;
}
copy_wasm_blobs(&source.join("bin"), &staging.join("bin"), &mut entries)?;
archive_inactive_activation_state(&staging, &mut entries).map_err(|error| {
io::Error::new(
error.kind(),
format!("failed to preserve imported activation state: {error}"),
)
})?;
ensure_no_ephemeral_data(&staging).map_err(|error| {
io::Error::new(
error.kind(),
format!("failed to validate ephemeral state exclusion: {error}"),
)
})?;
entries.sort_by(|left, right| left.path.cmp(&right.path));
let legacy_distros = legacy_distros(&staging).map_err(|error| {
io::Error::new(
error.kind(),
format!("failed to inspect imported distro locks: {error}"),
)
})?;
let receipt = Receipt {
migration_version: MIGRATION_VERSION,
schema_version: RECEIPT_SCHEMA_VERSION,
source: source.clone(),
entries,
legacy_distros,
};View on GitHub (pinned to f6f22024fb)