{"record":{"id":"02ed12d06eb42953","repo":"epi052/feroxbuster","slug":"could-not-get-underlying-commandsender-object","errorCode":null,"errorMessage":"Could not get underlying CommandSender object","messagePattern":"Could not get underlying CommandSender object","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/event_handlers/container.rs","lineNumber":129,"sourceCode":"    /// Set the ScanHandle object\n    pub fn set_scan_handle(&self, handle: ScanHandle) {\n        if let Ok(mut guard) = self.scans.write() {\n            if guard.is_none() {\n                guard.replace(handle);\n            }\n        }\n    }\n\n    /// Helper to easily send a Command over the (locked) underlying CommandSender object\n    pub fn send_scan_command(&self, command: Command) -> Result<()> {\n        if let Ok(guard) = self.scans.read().as_ref() {\n            if let Some(handle) = guard.as_ref() {\n                handle.send(command)?;\n                return Ok(());\n            }\n        }\n\n        bail!(\"Could not get underlying CommandSender object\")\n    }\n\n    /// wrapper to reach into `FeroxScans` and yank out the length of `collected_extensions`\n    pub fn num_collected_extensions(&self) -> usize {\n        if !self.config.collect_extensions {\n            // if --collect-extensions wasn't used, simply return 0 and forego unlocking\n            return 0;\n        }\n\n        self.collected_extensions().len()\n    }\n\n    /// wrapper to reach into `FeroxScans` and yank out the length of `collected_extensions`\n    pub fn collected_extensions(&self) -> HashSet<String> {\n        if let Ok(scans) = self.ferox_scans() {\n            if let Ok(extensions) = scans.collected_extensions.read() {\n                return extensions.clone();\n            }","sourceCodeStart":111,"sourceCodeEnd":147,"githubUrl":"https://github.com/epi052/feroxbuster/blob/1f595dab5c76858d5a14fbc47dabf2563d729c62/src/event_handlers/container.rs#L111-L147","documentation":"send_scan_command returns this error when the internal CommandSender handle cannot be retrieved. The container holds channel senders behind a read lock; if the guard fails or the slot is None (senders not initialized or already torn down), there is nothing to send the command through.","triggerScenarios":"Calling send_scan_command after the event loop/senders have been dropped or before initialization, or when the RwLock read guard yields None; typically during shutdown or in tests where the handler container was never started.","commonSituations":"Sending scan commands during application shutdown races with teardown; unit tests constructing a partial container without initialize(); a prior panic poisoned the senders map.","solutions":["Ensure the handler container is fully initialized (initialize/senders populated) before calling send_scan_command","Do not enqueue scan commands after initiating shutdown; join the event loop first","In tests, build the container through the standard constructor so senders are registered","Retry the call if it happens during shutdown rather than at startup"],"exampleFix":"// before\ncontainer.send_scan_command(Command::AddError)?; // during shutdown\n// after\nif !container.is_shutting_down() {\n    container.send_scan_command(Command::AddError)?;\n}","handlingStrategy":"try-catch","validationCode":"fn send_if_ready(container: &Container, cmd: Command) -> anyhow::Result<()> {\n    if container.is_shutting_down() {\n        return Ok(()); // nothing to send to\n    }\n    container.send_scan_command(cmd)\n}","typeGuard":null,"tryCatchPattern":"match container.send_scan_command(cmd) {\n    Ok(_) => {}\n    Err(e) if e.to_string().contains(\"Could not get underlying CommandSender\") => {\n        log::warn!(\"scan senders unavailable (shutting down?); dropping command\");\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Only send commands between container initialization and shutdown","Gracefully terminate the event loop before dropping the container","In tests, construct the container via its full constructor so senders exist"],"tags":["concurrency","internal-state","shutdown"],"backgroundTag":"internal-invariant-violation","analyzedSha":"1f595dab5c76858d5a14fbc47dabf2563d729c62","analyzedAt":"2026-09-13T19:33:06.208Z","contentChangedAt":"2026-09-13T19:33:06.208Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}