lima-vm/lima · error
directory entry %#q not found
Error message
directory entry %#q not found
What it means
lookupDirEntry scanned the leaf node of the directory B-tree for the given parent CNID and name and found no matching directory record. This is a structured not-found error: the tree was healthy, but no entry with that name exists in that directory. resolvePath raises it for each path component it cannot resolve.
Source
Thrown at pkg/apfs/chown.go:561
kOff, vOff := c.readTocEntry(blk, tocStart, i, isFixedKV)
keyStart := keyAreaStart + kOff
keyHeader := le.Uint64(blk[keyStart:])
if keyHeader != targetKeyHeader {
continue
}
// Parse the directory record key name.
entryName := c.readDrecName(blk, keyStart+8)
if entryName != name {
continue
}
// Read file_id from j_drec_val_t (first 8 bytes of value).
valStart := valueAreaEnd - vOff
return le.Uint64(blk[valStart:]), nil
}
return 0, fmt.Errorf("directory entry %#q not found", name)
}
// Internal node: find the child to descend into.
// The last key <= our target determines the child.
// For DIR_REC keys with matching headers, we also compare the
// name hash to find the correct subtree.
childIdx := uint32(0)
for i := range nkeys {
kOff, _ := c.readTocEntry(blk, tocStart, i, isFixedKV)
keyStart := keyAreaStart + kOff
cmp := c.compareDrecKey(blk, keyStart, targetKeyHeader, name, targetHash)
if cmp <= 0 {
childIdx = i
} else {
break
}
}
View on GitHub (pinned to dd909d0973)
Solutions
- Check the path exists in the target volume (list the directory contents on the host)
- Ensure names are NFD-normalized the way APFS stores them
- Verify you are resolving against the intended volume/snapshot, not an older one
- Handle the error by returning a clean not-found to your caller instead of treating it as corruption
Defensive patterns
Strategy: try-catch
Validate before calling
// Confirm the path component exists before resolution
// (e.g. list the directory via your own tooling or check on the host)
if !knownPathExistsInVolume(volumeID, path) {
return fmt.Errorf("path %q not present in volume %s", path, volumeID)
} Type guard
func isDirEntryNotFound(err error) bool {
return err != nil && strings.Contains(err.Error(), "directory entry") && strings.Contains(err.Error(), "not found")
} Try / catch
inode, err := c.resolvePath(root, omap, maxXID, path)
if isDirEntryNotFound(err) {
return os.ErrNotExist // clean not-found for callers
} Prevention
- Normalize paths to NFD before lookup (APFS stores NFD)
- Do not hard-code guest paths; validate against actual volume contents
- Remember snapshots may predate file creation
When it happens
Trigger: Calling resolvePath with a path containing a component that does not exist in the target volume (e.g. resolving '/etc/hosts' on a volume without 'etc'), a name differing in case/normalization from what is stored, or looking up in the wrong parent directory after a wrong earlier component resolved to an unexpected inode.
Common situations: Hard-coded guest paths that don't exist in the mounted volume; NFD vs NFC Unicode normalization mismatch for accented filenames; typos in path constants; resolving against a snapshot that predates file creation.
Related errors
- inode %d not found in filesystem B-tree
- resolving path %#q: %w
- looking up %#q in directory (cnid %d): %w
- filesystem B-tree node checksum failed
- filesystem B-tree node: %w
AI-assisted analysis of lima-vm/lima@dd909d0973 (2026-09-01).
Data as JSON: /api/errors/cb61129822329324.
Report an issue: GitHub.