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

  1. Inspect the wrapped inner error to identify which staged path failed, then fix that entry (permissions, broken symlink) and retry.
  2. Re-run the migration to rebuild the staging tree if the failure was transient (e.g. network filesystem hiccup).
  3. Exclude ephemeral/cache directories from the source before import so the staged tree is clean and scannable.
  4. 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

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


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)