{"record":{"id":"1617fd2d13596dfe","repo":"embassy-rs/embassy","slug":"zero-length-write","errorCode":null,"errorMessage":"zero-length write.","messagePattern":"zero-length write\\.","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"embassy-rp/src/uart/buffered.rs","lineNumber":808,"sourceCode":"}\n\nimpl<'d> embedded_io::Write for BufferedUartTx<'d> {\n    fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {\n        self.blocking_write(buf)\n    }\n\n    fn flush(&mut self) -> Result<(), Self::Error> {\n        self.blocking_flush()\n    }\n}\n\nimpl<'d> embedded_hal_02::blocking::serial::Write<u8> for BufferedUartTx<'d> {\n    type Error = Error;\n\n    fn bwrite_all(&mut self, mut buffer: &[u8]) -> Result<(), Self::Error> {\n        while !buffer.is_empty() {\n            match self.blocking_write(buffer) {\n                Ok(0) => panic!(\"zero-length write.\"),\n                Ok(n) => buffer = &buffer[n..],\n                Err(e) => return Err(e),\n            }\n        }\n        Ok(())\n    }\n\n    fn bflush(&mut self) -> Result<(), Self::Error> {\n        self.blocking_flush()\n    }\n}\n\nimpl<'d> embedded_hal_02::blocking::serial::Write<u8> for BufferedUart<'d> {\n    type Error = Error;\n\n    fn bwrite_all(&mut self, mut buffer: &[u8]) -> Result<(), Self::Error> {\n        while !buffer.is_empty() {\n            match self.blocking_write(buffer) {","sourceCodeStart":790,"sourceCodeEnd":826,"githubUrl":"https://github.com/embassy-rs/embassy/blob/463a07b963419a1bfe61d5d597c44acb810afb8b/embassy-rp/src/uart/buffered.rs#L790-L826","documentation":"The embedded-hal 0.2 blocking `Write::bwrite_all` implementation for `BufferedUartTx` treats a 0-byte result from `blocking_write` as an internal contract violation: the buffer was non-empty yet nothing was written and no error was returned, which would make the write loop spin forever. The library panics instead of looping infinitely.","triggerScenarios":"Calling `bwrite_all` (embedded-hal 0.2 blocking serial Write trait) when the underlying `blocking_write` returns Ok(0) — e.g. the buffered TX queue accepts/reports zero bytes written without an error, or a custom/latched error state that reports success with zero progress.","commonSituations":"Using the e-h-0.2 compatibility wrapper of buffered UART TX where the TX buffer is full in a way that yields zero writes; wiring `BufferedUartTx` into generic 0.2 serial code that loops on bwrite_all.","solutions":["Check UART/PIO configuration and error state before writing; ensure the buffered UART is properly initialized and the TX FIFO/queue is not wedged","Clear any error conditions (framing/overrun) on the UART before retrying the write","If writing generic code, prefer the embedded-hal 1.0 traits or embassy's native `blocking_write` API which returns errors instead of panicking on zero progress","Update embassy-rp — zero-progress handling in the buffered UART has been the subject of fixes; a newer version may return Err instead"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"// e-h 0.2 traits don't support catchable panics; prefer the native API which returns Result\nmatch tx.blocking_write(buf) {\n    Ok(n) if n == 0 => { /* treat as error: clear UART faults and retry */ }\n    Ok(_) => { /* progress */ }\n    Err(e) => { /* handle */ }\n}","preventionTips":["Prefer embedded-hal 1.0 traits or embassy's native write APIs over the 0.2 compat layer","Ensure the UART peer actually drains data (baud, wiring, flow control)","Clear UART error flags periodically in buffered write loops","Keep embassy-rp updated for buffered-UART zero-progress fixes"],"tags":["embedded","rp2040","uart","embedded-hal"],"backgroundTag":"internal-invariant-violation","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"}