charmbracelet/crush · error
cannot get ownership: %w
Error message
cannot get ownership: %w
What it means
traverseUp determines the owner of the starting directory via fsext.Owner so subsequent probes can enforce ownership boundaries. This error wraps any failure of Owner(dir), typically a stat failure on the starting directory.
Source
Thrown at internal/fsext/lookup.go:171
if err != nil {
return nil, err
}
return found, nil
}
// traverseUp walks up from given directory up until filesystem root reached.
// It passes absolute path of current directory and staring directory owner ID
// to callback function. It is up to user to check ownership.
func traverseUp(dir string, walkFn func(dir string, owner int) error) error {
cwd, err := filepath.Abs(dir)
if err != nil {
return fmt.Errorf("cannot convert CWD to absolute path: %w", err)
}
owner, err := Owner(dir)
if err != nil {
return fmt.Errorf("cannot get ownership: %w", err)
}
for {
err := walkFn(cwd, owner)
if err == nil || errors.Is(err, filepath.SkipDir) {
parent := filepath.Dir(cwd)
if parent == cwd {
return nil
}
cwd = parent
continue
}
if errors.Is(err, filepath.SkipAll) {
return nil
}
View on GitHub (pinned to 7944b8e522)
Solutions
- Verify dir exists and is accessible: run `stat <dir>` as the same user
- Correct the path (it may have been renamed/deleted) or recreate the directory
- Fix ownership/permissions so the running user can stat the directory
- If the directory may not exist, check os.Stat first and handle it explicitly rather than relying on the wrapped error
Example fix
// before
found, _ := fsext.LookupClosest(projectDir, ".crush.json")
// after
if _, err := os.Stat(projectDir); err != nil {
return fmt.Errorf("project dir %s unavailable: %w", projectDir, err)
}
found, _ := fsext.LookupClosest(projectDir, ".crush.json") Defensive patterns
Strategy: validation
Validate before calling
if fi, err := os.Stat(dir); err != nil {
return fmt.Errorf("cannot read starting dir %s: %w", dir, err)
} else if !fi.IsDir() {
return fmt.Errorf("%s is not a directory", dir)
} Type guard
func statableDir(dir string) bool {
fi, err := os.Stat(dir)
return err == nil && fi.IsDir()
} Try / catch
found, err := fsext.Lookup(dir, targets...)
if err != nil {
if strings.Contains(err.Error(), "cannot get ownership") {
// ownership unavailable — decide whether to proceed without boundary checks
return nil
}
return err
} Prevention
- Confirm the starting directory exists before lookups (projects can be moved/deleted)
- Ensure the runtime user can traverse (x) the full path to dir
- Avoid lookup roots on flaky automounts
- Handle dir-unavailable as a normal condition, not a crash
When it happens
Trigger: Calling Lookup/LookupClosest with a dir that cannot be stat'ed: the directory does not exist, the caller lacks permission on it, it was deleted concurrently, or it sits on a failed mount.
Common situations: Passing a project path that was renamed or removed; running with a user lacking search permission on the path (e.g. strict home directory perms); dangling paths on automounted volumes.
Related errors
- failed to access file: %w
- error accessing file: %w
- cannot stat %s: %w
- cannot get ownership for %s: %w
- failed to create parent directories: %w
AI-assisted analysis of charmbracelet/crush@7944b8e522 (2026-08-29).
Data as JSON: /api/errors/695bb15de479f815.
Report an issue: GitHub.