{"record":{"id":"b32c2e87f2fa133d","repo":"ClementTsang/bottom","slug":"ioregistryentrygetparententry-failed-error-code","errorCode":null,"errorMessage":"IORegistryEntryGetParentEntry failed, error code {result}.","messagePattern":"IORegistryEntryGetParentEntry failed, error code (.+?)\\.","errorType":"error_code","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"src/collection/disks/unix/macos/io_kit/io_object.rs","lineNumber":60,"sourceCode":"            } else {\n                let props = props.assume_init();\n                Ok(CFMutableDictionary::wrap_under_create_rule(props).to_immutable())\n            }\n        }\n    }\n\n    /// Gets the [`kIOServicePlane`] parent [`io_object_t`] for this\n    /// [`io_object_t`], if there is one.\n    pub fn service_parent(&self) -> anyhow::Result<IoObject> {\n        let mut parent: io_registry_entry_t = 0;\n\n        // SAFETY: IOKit call, the arguments should be safe.\n        let result = unsafe {\n            IORegistryEntryGetParentEntry(self.0, kIOServicePlane.as_ptr().cast(), &mut parent)\n        };\n\n        if result != kern_return::KERN_SUCCESS {\n            bail!(\"IORegistryEntryGetParentEntry failed, error code {result}.\")\n        } else {\n            Ok(parent.into())\n        }\n    }\n\n    // pub fn conforms_to_block_storage_driver(&self) -> bool {\n    //     // SAFETY: IOKit call, the arguments should be safe.\n    //     let result =\n    //         unsafe { IOObjectConformsTo(self.0,\n    // \"IOBlockStorageDriver\\0\".as_ptr().cast()) };\n\n    //     result != 0\n    // }\n}\n\nimpl From<io_object_t> for IoObject {\n    fn from(obj: io_object_t) -> IoObject {\n        IoObject(obj)","sourceCodeStart":42,"sourceCodeEnd":78,"githubUrl":"https://github.com/ClementTsang/bottom/blob/b77d3175028849824e987c35177e8f61450d72e7/src/collection/disks/unix/macos/io_kit/io_object.rs#L42-L78","documentation":"service_parent walks up the IOKit service plane (kIOServicePlane) via IORegistryEntryGetParentEntry to reach the parent of an IOKit entry (e.g. from IOSBlockStorageService up to its driver). A non-KERN_SUCCESS result is converted into this error.","triggerScenarios":"Calling service_parent() on an io_object that has no parent in the IOService plane or is not a valid registry entry — typically during the disk statistics traversal.","commonSituations":"Hot-unplugged devices mid-enumeration, synthetic/edge entries lacking parents, or entries from a stale iterator after system changes.","solutions":["Treat missing parents as a traversal boundary and stop walking up for that entry","Re-run disk enumeration to get fresh, valid IOKit entries","Inspect the kern_return_t code to distinguish 'no parent' from invalid entry","Skip that device's stats instead of failing the whole harvest"],"exampleFix":"// before\nlet parent = entry.service_parent()?;\n// after\nlet parent = match entry.service_parent() {\n    Ok(p) => p,\n    Err(e) => { log::debug!(\"no parent entry, stopping traversal: {e}\"); return None },\n};","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"let parent = match entry.service_parent() {\n    Ok(p) => Some(p),\n    Err(e) if e.to_string().contains(\"IORegistryEntryGetParentEntry\") => {\n        log::debug!(\"traversal boundary: {e}\"); None\n    },\n    Err(e) => return Err(e),\n};","preventionTips":["Treat a missing parent as end-of-traversal, not a fatal error","Refresh the device iterator on every collection cycle","Don't reuse io_object handles across sweeps","Record kern_return_t codes for support diagnostics"],"tags":["macos","iokit","disks","system-api"],"backgroundTag":"api-error-response","analyzedSha":"b77d3175028849824e987c35177e8f61450d72e7","analyzedAt":"2026-09-07T14:53:21.246Z","contentChangedAt":"2026-09-07T14:53:21.246Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}