astrid-runtime/astrid · error
legacy source entry is group/world writable: {}
Error message
legacy source entry is group/world writable: {} What it means
Under SourceAccess::OwnerControlled, entries must not be group- or world-writable: if metadata.mode() & 0o022 != 0 the migration fails with PermissionDenied. Group/world-writable files could be modified by other principals, so the owner-controlled guarantee (contents controlled solely by the owner) would not hold.
Source
Thrown at crates/astrid-kernel/src/legacy_migration_barrier/host_fs.rs:786
io::ErrorKind::InvalidData,
format!("legacy source contains a special entry: {}", path.display()),
));
}
#[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!(
"legacy source entry is not owned by the current user: {}",
path.display()
),
));
}
if metadata.mode() & 0o022 != 0 {
return Err(io::Error::new(
io::ErrorKind::PermissionDenied,
format!(
"legacy source entry is group/world writable: {}",
path.display()
),
));
}
astrid_core::platform_fs::validate_no_extended_acl(path)?;
Ok(())
}
#[cfg(not(unix))]
{
validate_private_entry(path, metadata)
}
}
fn read_regular_file(
path: &Path,View on GitHub (pinned to affd8760f4)
Solutions
- Tighten permissions: `chmod -R go-w <source>` (e.g. dirs to 0750, files to 0640)
- Set a restrictive umask (022 or 077) and recreate/rewrite the offending files
- Use SourceAccess::Private if the group/world-writable profile is acceptable in your environment
Example fix
// before: files are group-writable (0664) let result = snapshot_path_with_access(path, SourceAccess::OwnerControlled); // Err: legacy source entry is group/world writable: ... // after: strip group/world write bits, then migrate // $ chmod -R go-w /home/alice/data let result = snapshot_path_with_access(path, SourceAccess::OwnerControlled);
Defensive patterns
Strategy: validation
Validate before calling
#[cfg(unix)]
fn assert_not_group_or_world_writable(source: &std::path::Path) -> std::io::Result<()> {
use std::os::unix::fs::MetadataExt;
let mut stack = vec![source.to_path_buf()];
while let Some(dir) = stack.pop() {
for entry in std::fs::read_dir(&dir)? {
let path = entry?.path();
let md = std::fs::symlink_metadata(&path)?;
if md.mode() & 0o022 != 0 {
return Err(std::io::Error::new(
std::io::ErrorKind::PermissionDenied,
format!("group/world writable: {}", path.display()),
));
}
if md.is_dir() {
stack.push(path);
}
}
}
Ok(())
} Try / catch
match snapshot_path_with_access(source, SourceAccess::OwnerControlled) {
Err(e) if e.kind() == std::io::ErrorKind::PermissionDenied
&& e.to_string().contains("group/world writable") =>
{
eprintln!("fix with: chmod -R go-w <source>");
}
other => other?,
} Prevention
- Run with a restrictive umask (022 or 077) when writing into the source tree
- Audit with `find <source> -perm /022` before migrating
- Avoid syncing source data from FAT/exFAT filesystems that force permissive modes
- Tighten shared working directories to 0750/0640 instead of 0775/0664
When it happens
Trigger: Calling the migration API with SourceAccess::OwnerControlled where any file or directory in the source has mode bits 0o020 (group write) or 0o002 (other write) set — e.g. modes like 0664 files, 0775/0777 dirs, or umask-less tools writing 0666 files.
Common situations: Files created with a permissive umask (000) or by tools that force 0666; shared working directories using 0775; defaults of some archive extractors or editors; data copied from FAT/exFAT mounts with permissive modes.
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: {}
- capsule projection path is not UTF-8: {}
- unexpected entry in released legacy SurrealKV source: {}
- private file is not owner-only: {}
- legacy source is not a regular file: {}
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/73e29048fd1b3a4e.
Report an issue: GitHub.