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

  1. Re-run the lookup; a transient race between the two stat calls usually resolves on retry
  2. Check permissions/ownership of the specific path with `ls -la <path>` and `stat <path>`
  3. Exclude unstable mounts (FUSE/NFS) from the lookup's starting directory
  4. 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

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


AI-assisted analysis of charmbracelet/crush@7944b8e522 (2026-08-29). Data as JSON: /api/errors/af0190d5f679533e. Report an issue: GitHub.