{"record":{"id":"d17976d7c0b80097","repo":"lima-vm/lima","slug":"resolving-child-oid-d-w","errorCode":null,"errorMessage":"resolving child OID %d: %w","messagePattern":"resolving child OID (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/apfs/chown.go","lineNumber":585,"sourceCode":"\t\t// name hash to find the correct subtree.\n\t\tchildIdx := uint32(0)\n\t\tfor i := range nkeys {\n\t\t\tkOff, _ := c.readTocEntry(blk, tocStart, i, isFixedKV)\n\t\t\tkeyStart := keyAreaStart + kOff\n\t\t\tcmp := c.compareDrecKey(blk, keyStart, targetKeyHeader, name, targetHash)\n\t\t\tif cmp <= 0 {\n\t\t\t\tchildIdx = i\n\t\t\t} else {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\t// Read child OID (virtual) and resolve through omap.\n\t\t_, vOff := c.readTocEntry(blk, tocStart, childIdx, isFixedKV)\n\t\tchildOID := le.Uint64(blk[valueAreaEnd-vOff:])\n\t\tchildPhys, err := c.omapLookup(omapTreeAddr, childOID, maxXID)\n\t\tif err != nil {\n\t\t\treturn 0, fmt.Errorf(\"resolving child OID %d: %w\", childOID, err)\n\t\t}\n\t\tblk, err = c.readBlock(childPhys)\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t}\n}\n\n// readDrecName reads a directory record name from the key data\n// starting at nameFieldOff. Handles both hashed (j_drec_hashed_key_t,\n// 4-byte name_len_and_hash) and non-hashed (j_drec_key_t, 2-byte\n// name_len) formats.\nfunc (c *container) readDrecName(blk []byte, nameFieldOff uint32) string {\n\t// Heuristic: if the 4-byte field at nameFieldOff has its upper\n\t// bits set (hash), it's a hashed key. For non-hashed keys, the\n\t// 2-byte name_len is followed by the name bytes.\n\t//\n\t// In j_drec_hashed_key_t: name_len_and_hash (uint32) where","sourceCodeStart":567,"sourceCodeEnd":603,"githubUrl":"https://github.com/lima-vm/lima/blob/dd909d0973cd84fa35f9e1693181b4585ea616c1/pkg/apfs/chown.go#L567-L603","documentation":"This error wraps a failure from omapLookup while descending an internal B-tree node in lookupDirEntry: the child block's virtual OID could not be translated to a physical address through the object map. The %d is the virtual OID and %w the underlying omap error (typically 'not found' or an omap node failure).","triggerScenarios":"resolvePath descends into a child node whose virtual OID is absent from the omap tree for the given maxXID — the child was created after maxXID (stale transaction snapshot), the wrong omap tree address was supplied, or the omap entry was deleted by a rebalance/cleanup.","commonSituations":"Reading an old snapshot (maxXID too low) while the live tree was modified; passing the live omap root to a snapshot tree walk; corrupted or mismatched container superblock selection on multi-volume images.","solutions":["Use the max XID (latest transaction) consistent with the tree you are walking","Pass the omap tree address belonging to the same volume/superblock as fsRootPhys","Run fsck_apfs to repair a damaged omap","Re-read the container superblock and re-resolve both tree roots before walking"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// Use the latest transaction ID so omap entries exist\nmaxXID := readContainerMaxXID(containerSuperblock)\nif maxXID == 0 {\n    return errors.New(\"invalid maxXID: use latest container transaction\")\n}","typeGuard":"func isOmapResolutionError(err error) bool {\n    return err != nil && strings.Contains(err.Error(), \"resolving child OID\")\n}","tryCatchPattern":"inode, err := c.resolvePath(root, omap, maxXID, path)\nif isOmapResolutionError(err) {\n    // re-read superblock for fresh tree roots and retry once\n    fsRoot, omapTree, maxXID = reResolveRoots()\n    inode, err = c.resolvePath(fsRoot, omapTree, maxXID, path)\n}","preventionTips":["Always re-read the container superblock immediately before a walk","Match snapshot tree with the snapshot's omap, live tree with live omap","Never use a lower maxXID than the generation of the tree you walk"],"tags":["apfs","omap","b-tree","oid-resolution","snapshot"],"backgroundTag":"omap-lookup-failed","analyzedSha":"dd909d0973cd84fa35f9e1693181b4585ea616c1","analyzedAt":"2026-09-01T14:24:59.842Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}