astrid-runtime/astrid · error
legacy audit retirement source is outside the default princi
Error message
legacy audit retirement source is outside the default principal audit path
What it means
retire_legacy_audit_dir only retires the exact default principal audit directory (home.principal_home(&PrincipalId::default()).audit_dir()). If the caller passes any other source path, the function rejects it with InvalidInput before performing any traversal or deletion, as a guard against retiring arbitrary directories. The message carries no path since it is a programmatic argument check.
Source
Thrown at crates/astrid-kernel/src/legacy_migration_barrier/host_fs.rs:450
format!(
"unsupported legacy audit source {}; only the default principal source is admitted",
audit_source.display()
),
));
}
}
Ok(default_source_present)
}
/// Retire the imported default audit tree through a private staging rename.
/// The rename makes interrupted deletion resumable, while every pre/post
/// traversal revalidates no-follow, regular-entry, device, and mount bounds.
#[cfg(not(unix))]
pub(super) fn retire_legacy_audit_dir(home: &AstridHome, source: &Path) -> io::Result<()> {
let retired = home.migrations_dir().join("audit-principal-home.retired");
let expected = home.principal_home(&PrincipalId::default()).audit_dir();
if source != expected {
return Err(io::Error::new(
io::ErrorKind::InvalidInput,
"legacy audit retirement source is outside the default principal audit path",
));
}
astrid_core::platform_fs::verify_no_redirects(source.parent().ok_or_else(|| {
io::Error::new(
io::ErrorKind::InvalidInput,
"legacy audit source has no parent",
)
})?)?;
astrid_core::platform_fs::ensure_private_directory(&home.migrations_dir())?;
astrid_core::platform_fs::verify_no_redirects(&home.migrations_dir())?;
match fs::symlink_metadata(source) {
Ok(metadata) if metadata.file_type().is_symlink() || !metadata.is_dir() => {
return Err(io::Error::new(
io::ErrorKind::InvalidData,
format!(
"legacy audit source is not a regular directory: {}",View on GitHub (pinned to affd8760f4)
Solutions
- Pass exactly home.principal_home(&PrincipalId::default()).audit_dir() as the source argument.
- Normalize the source path (canonicalize or construct it from AstridHome APIs) instead of assembling it from strings.
- If migrating a non-default principal's audit dir, do not use this API — it only supports the default principal.
- Check for trailing slashes or duplicated separators in the path you pass and remove them.
Example fix
// before
retire_legacy_audit_dir(&home, &Path::from("/home/u/.astrid/principals/other/audit"))?;
// after
let source = home.principal_home(&PrincipalId::default()).audit_dir();
retire_legacy_audit_dir(&home, &source)?; Defensive patterns
Strategy: type-guard
Validate before calling
fn source_is_default(home: &AstridHome, source: &std::path::Path) -> bool {
source == home.principal_home(&PrincipalId::default()).audit_dir()
} Type guard
fn expected_retirement_source(home: &AstridHome) -> std::path::PathBuf {
home.principal_home(&PrincipalId::default()).audit_dir()
} Try / catch
match result {
Err(e) if e.kind() == std::io::ErrorKind::InvalidInput && e.to_string().contains("outside the default principal audit path") => {
// rebuild the path via AstridHome APIs and retry
}
other => other?,
} Prevention
- Always derive the source from AstridHome accessors, never from raw strings.
- Avoid path normalization drift (trailing slashes, .., symlinked parents) when passing paths.
- Only the default principal's audit dir is retirable — route other paths elsewhere.
When it happens
Trigger: Calling retire_legacy_audit_dir(home, source) (via migrate_legacy_audit) with a source path that is not byte-identical to the default principal audit dir — e.g. a trailing slash difference, a non-default principal's audit dir, or a hand-constructed path (host_fs.rs:449).
Common situations: Custom migration scripts passing their own path; tests exercising retirement with a fabricated source; path normalization differences (//, trailing separator, symlinked parents) between the caller's path and the computed expected path.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- layout path has no existing directory ancestor: {}
- layout migration receipt destination path does not match the
- unsupported legacy audit source {}; only the default princip
- InvalidData
- unsupported legacy audit source {audit_source}; only the def
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/dc69b1acd1d9bff6.
Report an issue: GitHub.