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

  1. Check the path exists in the target volume (list the directory contents on the host)
  2. Ensure names are NFD-normalized the way APFS stores them
  3. Verify you are resolving against the intended volume/snapshot, not an older one
  4. 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

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


AI-assisted analysis of lima-vm/lima@dd909d0973 (2026-09-01). Data as JSON: /api/errors/cb61129822329324. Report an issue: GitHub.