astrid-runtime/astrid · error
ordinary legacy file is not owned by the current user
Error message
ordinary legacy file is not owned by the current user: {path} What it means
Raised by validate_regular_file when an ordinary legacy file's owner uid differs from the current process uid (unix only). Migration refuses to ingest files the current user does not own, since trusting foreign-owned files would be a security risk. ErrorKind::PermissionDenied.
Solutions
- chown the legacy files to the current user (e.g. sudo chown -R $(id -u) <path>)
- Re-copy the legacy home as the current user without sudo
- Run the migration as the owner of the files
- Exclude the foreign-owned files from the legacy source tree
Example fix
// before: migration fails on root-owned files sudo cp -r /old/home ~/legacy-home # files owned by root // after: take ownership first sudo chown -R $(id -u):$(id -g) ~/legacy-home
Defensive patterns
Strategy: validation
Validate before calling
#[cfg(unix)]
fn all_files_owned_by_me(root: &Path) -> bool {
use std::os::unix::fs::MetadataExt;
walk(root).all(|p| p.metadata().map(|m| m.uid() == nix::unistd::getuid().as_raw()).unwrap_or(false))
} Type guard
#[cfg(unix)]
fn owned_by_current_user(m: &std::fs::Metadata) -> bool {
use std::os::unix::fs::MetadataExt;
m.uid() == nix::unistd::getuid().as_raw()
} Try / catch
match migrate(...) {
Err(e) if e.kind() == io::ErrorKind::PermissionDenied => {
eprintln!("fix ownership: chown -R $(id -u) <legacy home>");
Err(e)
}
other => other,
} Prevention
- Never copy legacy homes with sudo; copy as the migrating user
- Run chown -R before migration when files arrive from backups
- Run the migration under the same account that owns the legacy data
When it happens
Trigger: Calling digest_file or publish_directory_files (via migrate_legacy_principal_homes) when a regular file under the legacy source tree has metadata.uid() != getuid().
Common situations: Legacy homes copied with sudo/root ownership, files restored from backups as root, shared multi-user machines where another user created files in the migrated tree.
Understand the failure class
Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.
Related errors
- legacy source entry is not owned by the current user
- ordinary legacy file is group/world writable
- PermissionDenied
- PermissionDenied
- private directory is not owned by the current user
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/4a7e8f8ca616340a.
Report an issue: GitHub.
Appendix: source
Thrown at crates/astrid-kernel/src/principal_home_migration/mod.rs:873
}
Ok((
ByteCount::new(bytes),
ContentDigest::from_blake3(hasher.finalize()),
))
}
fn validate_regular_file(path: &Path) -> io::Result<()> {
let metadata = fs::symlink_metadata(path)?;
if metadata.file_type().is_symlink() || !metadata.is_file() {
return Err(invalid_source(path, "ordinary entry is not a regular file"));
}
astrid_core::platform_fs::verify_no_redirects(path)?;
#[cfg(unix)]
{
use std::os::unix::fs::MetadataExt as _;
if metadata.uid() != nix::unistd::getuid().as_raw() {
return Err(io::Error::new(
io::ErrorKind::PermissionDenied,
format!(
"ordinary legacy file is not owned by the current user: {}",
path.display()
),
));
}
if metadata.mode() & 0o022 != 0 {
return Err(io::Error::new(
io::ErrorKind::PermissionDenied,
format!(
"ordinary legacy file is group/world writable: {}",
path.display()
),
));
}
}
Ok(())View on GitHub (pinned to affd8760f4)