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
- Investigate the named directory, move/import any remaining secret files, and re-run migration.
- Ensure no processes write new secrets into the legacy root during migration.
- 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
- Ensure no processes write new secrets into the legacy root during migration.
- Verify all expected secret filenames are handled by the migration patterns.
- Run migration once to completion; avoid partial/interrupted runs.
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
- durable capsule failed authoritative verification
- InvalidData
- InvalidData
- layout cutover record is empty
- layout cutover record is not a regular file
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)