{"record":{"id":"7e26a9bfd40c4bc8","repo":"embassy-rs/embassy","slug":"bad-mailbox","errorCode":null,"errorMessage":"Bad mailbox","messagePattern":"Bad mailbox","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"embassy-stm32/src/can/fdcan.rs","lineNumber":329,"sourceCode":"    properties: Properties,\n    info: InfoRef,\n}\n\nimpl<'d> Can<'d> {\n    /// Get driver properties\n    pub fn properties(&self) -> &Properties {\n        &self.properties\n    }\n\n    /// Flush one of the TX mailboxes.\n    pub async fn flush(&self, idx: usize) {\n        poll_fn(|cx| {\n            self.info.state.lock(|s| {\n                s.borrow_mut().tx_mode.register(cx.waker());\n            });\n\n            if idx > 3 {\n                panic!(\"Bad mailbox\");\n            }\n            let idx = 1 << idx;\n            if !self.info.regs.regs.txbrp().read().trp(idx) {\n                return Poll::Ready(());\n            }\n\n            Poll::Pending\n        })\n        .await;\n    }\n\n    /// Queues the message to be sent but exerts backpressure.  If a lower-priority\n    /// frame is dropped from the mailbox, it is returned.  If no lower-priority frames\n    /// can be replaced, this call asynchronously waits for a frame to be successfully\n    /// transmitted, then tries again.\n    pub async fn write(&mut self, frame: &Frame) -> Option<Frame> {\n        TxMode::write(&self.info, frame).await\n    }","sourceCodeStart":311,"sourceCodeEnd":347,"githubUrl":"https://github.com/embassy-rs/embassy/blob/463a07b963419a1bfe61d5d597c44acb810afb8b/embassy-stm32/src/can/fdcan.rs#L311-L347","documentation":"`FdcanTxFrame::flush` panics with \"Bad mailbox\" when the transmit mailbox index is greater than 3. The FDCAN peripheral provides at most 4 TX buffers used as mailboxes, so any index beyond that is an invalid argument. Because it is a panic, it aborts the task rather than returning an error.","triggerScenarios":"Calling `flush(idx)` (or APIs that forward to it, like awaiting a transmitted frame handle) with a mailbox index > 3 — e.g. iterating mailboxes with the wrong limit or reusing an index from a differently-configured buffer count.","commonSituations":"Hardcoding mailbox counts instead of using the driver's constants; code written for other CAN peripherals with more mailboxes; off-by-one loops over `0..=3` becoming `0..4` on inclusive ranges.","solutions":["Only use mailbox indices 0..=3 as returned by the driver's split_tx/queue APIs.","Iterate with `0..NUM_MAILBOXES` rather than hardcoded numbers.","Track mailbox handles returned by the driver instead of synthesizing indices."],"exampleFix":"// before\nfor idx in 0..8 {\n    tx.flush(idx).await;\n}\n// after\nfor idx in 0..4 {\n    tx.flush(idx).await;\n}","handlingStrategy":"validation","validationCode":"fn valid_mailbox(idx: usize) -> bool { idx < 4 }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["FDCAN has at most 4 TX mailboxes; never hardcode larger counts.","Use mailbox handles/indices returned by the driver's split APIs.","Derive loop bounds from constants, not magic numbers."],"tags":["embedded","can","panic","mailbox","range-check"],"backgroundTag":"value-out-of-range","analyzedSha":"463a07b963419a1bfe61d5d597c44acb810afb8b","analyzedAt":"2026-09-10T13:38:26.660Z","contentChangedAt":"2026-09-10T13:38:26.660Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}