{"record":{"id":"896d050607c3e7c2","repo":"rust-embedded/rust-raspberrypi-OS-tutorials","slug":"error-during-driver-post-init-callback","errorCode":null,"errorMessage":"Error during driver post-init callback: {}: {}","messagePattern":"Error during driver post-init callback: (.+?): (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"20_timer_callbacks/kernel/src/driver.rs","lineNumber":142,"sourceCode":"    /// # Safety\n    ///\n    /// - During init, drivers might do stuff with system-wide impact.\n    pub unsafe fn init_drivers_and_irqs(&self) {\n        self.descriptors.read(|descriptors| {\n            for descriptor in descriptors {\n                // 1. Initialize driver.\n                if let Err(x) = descriptor.device_driver.init() {\n                    panic!(\n                        \"Error initializing driver: {}: {}\",\n                        descriptor.device_driver.compatible(),\n                        x\n                    );\n                }\n\n                // 2. Call corresponding post init callback.\n                if let Some(callback) = &descriptor.post_init_callback {\n                    if let Err(x) = callback() {\n                        panic!(\n                            \"Error during driver post-init callback: {}: {}\",\n                            descriptor.device_driver.compatible(),\n                            x\n                        );\n                    }\n                }\n            }\n\n            // 3. After all post-init callbacks were done, the interrupt controller should be\n            //    registered and functional. So let drivers register with it now.\n            for descriptor in descriptors {\n                if let Some(irq_number) = &descriptor.irq_number {\n                    if let Err(x) = descriptor\n                        .device_driver\n                        .register_and_enable_irq_handler(irq_number)\n                    {\n                        panic!(\n                            \"Error during driver interrupt handler registration: {}: {}\",","sourceCodeStart":124,"sourceCodeEnd":160,"githubUrl":"https://github.com/rust-embedded/rust-raspberrypi-OS-tutorials/blob/644474cc09f755249f9c55d99a5d1e07a2562fc7/20_timer_callbacks/kernel/src/driver.rs#L124-L160","documentation":"A driver registered a post-init callback with its descriptor; after the driver's init() succeeds, init_drivers_and_irqs invokes that callback, and it returned Err. The manager panics, naming the driver via its compatible string and the callback's error message. Post-init callbacks encode cross-driver or system-level setup, so their failure aborts bring-up.","triggerScenarios":"A DeviceDriverDescriptor was constructed with Some(post_init_callback) and that closure/function returns Err when called during init_drivers_and_irqs().","commonSituations":"The callback enables peripherals or registers global state and hits an unmet precondition (IRQ manager not yet set, dependent driver not initialized); the callback was copied from another driver and references wrong hardware; ordering of driver registration changed so a dependency is missing.","solutions":["Read the compatible name and error payload in the panic message to locate the failing callback.","Fix the callback so its operation succeeds, or move its work into the driver's init() if that is the right phase.","Ensure dependent subsystems (e.g. IRQ manager) are registered before init_drivers_and_irqs runs.","If the callback is optional for the current board, drop it from the descriptor."],"exampleFix":"// before\nlet desc = DeviceDriverDescriptor::new(driver, Some(post_init))\n    .with_irq_number(irq); // post_init calls irq_manager before it exists\n\n// after\n// register the IRQ manager first, or remove the eager IRQ setup from post_init\nfn post_init() -> Result<(), &'static str> {\n    // safe: dependencies are up by the time this runs\n    setup_timer_interrupt()\n}","handlingStrategy":"validation","validationCode":"// before registering a descriptor, ensure callback dependencies exist:\nif post_init_needs_irq_manager() && !irq_manager_registered() {\n    return Err(\"post_init requires an IRQ manager that is not yet registered\");\n}","typeGuard":null,"tryCatchPattern":"// replace panic in callback dispatch with logged failure:\nif let Err(x) = callback() {\n    log_warn(\"post-init callback failed for {}: {}\", descriptor.device_driver.compatible(), x);\n}","preventionTips":["Document which subsystems each post_init callback depends on and enforce registration order.","Keep post_init callbacks minimal; prefer doing work inside the driver's own init().","Review descriptors when changing driver registration order."],"tags":["rust","driver","callback","panic","boot"],"backgroundTag":"module-init-failed","analyzedSha":"644474cc09f755249f9c55d99a5d1e07a2562fc7","analyzedAt":"2026-09-06T09:25:56.584Z","contentChangedAt":"2026-09-06T09:25:56.584Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}