charmbracelet/crush · error
cannot get ownership for %s: %w
Error message
cannot get ownership for %s: %w
What it means
After confirming the path exists, probeEnt queries the file's owner with fsext.Owner to enforce that lookups never cross ownership boundaries. This error wraps a failure of Owner(fspath) on an existing entity — usually a stat/ownership syscall failure on that specific path.
Source
Thrown at internal/fsext/lookup.go:273
}
return filepath.Clean(path)
}
// probeEnt checks if entity at given path exists and belongs to given owner
func probeEnt(fspath string, owner int) error {
_, err := os.Stat(fspath)
if err != nil {
return fmt.Errorf("cannot stat %s: %w", fspath, err)
}
// special case for ownership check bypass
if owner == -1 {
return nil
}
fowner, err := Owner(fspath)
if err != nil {
return fmt.Errorf("cannot get ownership for %s: %w", fspath, err)
}
if fowner != owner {
return os.ErrPermission
}
return nil
}
View on GitHub (pinned to 7944b8e522)
Solutions
- Re-run the lookup; a transient race between the two stat calls usually resolves on retry
- Check permissions/ownership of the specific path with `ls -la <path>` and `stat <path>`
- Exclude unstable mounts (FUSE/NFS) from the lookup's starting directory
- If persistent, verify the running user can stat all files in the search tree
Example fix
// before
found, err := fsext.Lookup(dir, target)
if err != nil {
return err
}
// after — retry once on ownership-query failures
found, err := fsext.Lookup(dir, target)
if err != nil && strings.Contains(err.Error(), "cannot get ownership") {
time.Sleep(50 * time.Millisecond)
found, err = fsext.Lookup(dir, target)
}
if err != nil {
return err
} Defensive patterns
Strategy: retry
Validate before calling
// Ensure the runtime user can stat-and-read ownership of the search root
var st os.FileInfo
var err error
if st, err = os.Stat(dir); err != nil {
return fmt.Errorf("search root unreadable: %w", err)
}
_ = st
Type guard
func ownershipQueryable(path string) bool {
_, err := fsext.Owner(path)
return err == nil
} Try / catch
var found []string
var err error
for i := 0; i < 3; i++ {
found, err = fsext.Lookup(dir, targets...)
if err == nil || !strings.Contains(err.Error(), "cannot get ownership") {
break
}
time.Sleep(50 * time.Millisecond) // transient TOCTOU on mounts
}
if err != nil {
return err
} Prevention
- Avoid running lookups while other processes chmod/chown the tree
- Exclude flaky FUSE/NFS mounts from search roots
- Prefer local disks for project directories the lookup walks
- If it persists, check ACLs/LSM policies (SELinux) blocking stat on the file
When it happens
Trigger: The candidate file/dir exists but its owner cannot be determined: permission denied on the path itself despite existing (race where it became unreadable), failed mount, or an OS-level stat error between the initial os.Stat and the Owner check (TOCTOU).
Common situations: Files changing permissions mid-lookup (another process chmod'ing); FUSE/network filesystems flaking between two stat calls; security-hardened environments where stat on other users' files is blocked.
Related errors
- failed to read file: %w
- cannot get ownership: %w
- workspace closing
- failed to create parent directories: %w
- failed to create output file: %w
AI-assisted analysis of charmbracelet/crush@7944b8e522 (2026-08-29).
Data as JSON: /api/errors/af0190d5f679533e.
Report an issue: GitHub.