astrid-runtime/astrid · error

ordinary legacy file is group/world writable

Error message

ordinary legacy file is group/world writable: {path}

What it means

Raised by validate_regular_file when an ordinary legacy file is group-writable or world-writable (mode & 0o022 != 0). Overly permissive legacy files are rejected to preserve the private-directory-tree guarantee the migration builds. ErrorKind::PermissionDenied.

Solutions

  1. Tighten permissions: chmod go-w <path> (or chmod 600 for the whole tree)
  2. Run chmod -R go-rwx on the legacy source root before migrating
  3. Check the umask/origin tooling that created 0666 files and fix the source
  4. Re-run migration after the tree satisfies the private-directory requirements

Example fix

// before: file mode 0664 aborts migration
-rw-rw-r-- legacy-home/notes.txt
// after: restrict to owner-only
chmod 600 legacy-home/notes.txt
Defensive patterns

Strategy: validation

Validate before calling

#[cfg(unix)]
fn no_group_world_writable(root: &Path) -> bool {
    use std::os::unix::fs::PermissionsExt;
    walk(root).all(|p| p.metadata().map(|m| m.permissions().mode() & 0o022 == 0).unwrap_or(false))
}

Type guard

#[cfg(unix)]
fn is_owner_writable_only(m: &std::fs::Metadata) -> bool {
    use std::os::unix::fs::PermissionsExt;
    m.permissions().mode() & 0o022 == 0
}

Try / catch

match migrate(...) {
    Err(e) if e.kind() == io::ErrorKind::PermissionDenied => {
        eprintln!("tighten modes: chmod -R go-w <legacy home>");
        Err(e)
    }
    other => other,
}

Prevention

When it happens

Trigger: Calling digest_file or publish_directory_files (via migrate_legacy_principal_homes) when a regular file's permission mode has group or other write bits set (e.g. 0666, 0664).

Common situations: Files shared via group permissions from an old setup, umask-less tools creating 0666 files, legacy homes synced from systems with looser defaults.

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


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

Appendix: source

Thrown at crates/astrid-kernel/src/principal_home_migration/mod.rs:882

    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(())
}

#[cfg(test)]
mod tests;

View on GitHub (pinned to affd8760f4)