astrid-runtime/astrid · error

legacy secret source remains after migration

Error message

legacy secret source remains after migration: {}

What it means

After migration, every legacy secret source directory (except `__host__`) must be empty — its snapshot entry count must be 0. A non-empty snapshot means the migration failed to consume all secret files, and the library raises `InvalidData` naming the path.

Solutions

  1. Investigate the named directory, move/import any remaining secret files, and re-run migration.
  2. Ensure no processes write new secrets into the legacy root during migration.
  3. Manually clear the legacy directory once its contents are accounted for.

Example fix

# before: legacy dir still has leftovers
ls legacy-secrets/api/  # token.txt still present
# after: migrate leftovers then re-run
astrid migrate --include legacy-secrets/api/token.txt
Defensive patterns

Strategy: validation

Validate before calling

fn legacy_fully_migrated(legacy_root: &std::path::Path) -> bool {
    std::fs::read_dir(legacy_root).map(|rd| rd.filter_map(Result::ok)
        .filter(|e| e.file_name() != "__host__")
        .all(|e| std::fs::read_dir(e.path()).map(|mut d| d.next().is_none()).unwrap_or(false)))
    .unwrap_or(false)
}

Try / catch

match ensure_legacy_secret_aliases(root, ...) {
    Err(e) if e.to_string().contains("remains after migration") => {
        let dir = extract_path(&e); // from message
        eprintln!("leftover secrets in {dir}; import them and re-run");
        return Err(e.into());
    }
    other => other,
}

Prevention

When it happens

Trigger: Calling `ensure_legacy_secret_aliases` during post-migration verification when `snapshot_path(path).entries != 0` for a legacy source directory.

Common situations: New secret files appeared in the legacy directory during migration (running app wrote a credential); some files were skipped due to names not matching expected patterns; a partially failed prior migration left files behind.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09). Data as JSON: /api/errors/c7ac3c81eed659de. Report an issue: GitHub.

Appendix: source

Thrown at crates/astrid-kernel/src/legacy_migration_barrier/host_fs.rs:110

                "legacy secrets root is not a regular directory: {}",
                root.display()
            ),
        ));
    }
    astrid_core::platform_fs::validate_private_directory(root)?;
    astrid_core::platform_fs::verify_no_redirects(root)?;
    let entries = fs::read_dir(root)
        .map_err(io::Error::other)?
        .collect::<Result<Vec<_>, _>>()
        .map_err(io::Error::other)?;
    for entry in entries {
        if entry.file_name() == "__host__" {
            continue;
        }
        let path = entry.path();
        let snapshot = snapshot_path(&path)?;
        if snapshot.entries != 0 {
            return Err(io::Error::new(
                io::ErrorKind::InvalidData,
                format!(
                    "legacy secret source remains after migration: {}",
                    path.display()
                ),
            ));
        }
        if allow_empty_cleanup {
            retire_empty_directory(&path)?;
        } else {
            return Err(io::Error::new(
                io::ErrorKind::InvalidData,
                format!(
                    "legacy secret source reappeared after cut-over: {}",
                    path.display()
                ),
            ));
        }

View on GitHub (pinned to affd8760f4)