{"record":{"id":"037f4fa2820528e0","repo":"embassy-rs/embassy","slug":"unwrap-of-failed-037f4f","errorCode":null,"errorMessage":"unwrap of `{}` failed: {:?}","messagePattern":"unwrap of `(.+?)` failed: (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"embassy-rp/src/fmt.rs","lineNumber":202,"sourceCode":"    };\n}\n\n#[cfg(feature = \"defmt\")]\n#[collapse_debuginfo(yes)]\nmacro_rules! unwrap {\n    ($($x:tt)*) => {\n        ::defmt::unwrap!($($x)*)\n    };\n}\n\n#[cfg(not(feature = \"defmt\"))]\n#[collapse_debuginfo(yes)]\nmacro_rules! unwrap {\n    ($arg:expr) => {\n        match $crate::fmt::Try::into_result($arg) {\n            ::core::result::Result::Ok(t) => t,\n            ::core::result::Result::Err(e) => {\n                ::core::panic!(\"unwrap of `{}` failed: {:?}\", ::core::stringify!($arg), e);\n            }\n        }\n    };\n    ($arg:expr, $($msg:expr),+ $(,)? ) => {\n        match $crate::fmt::Try::into_result($arg) {\n            ::core::result::Result::Ok(t) => t,\n            ::core::result::Result::Err(e) => {\n                ::core::panic!(\"unwrap of `{}` failed: {}: {:?}\", ::core::stringify!($arg), ::core::format_args!($($msg,)*), e);\n            }\n        }\n    }\n}\n\n#[derive(Debug, Copy, Clone, Eq, PartialEq)]\npub struct NoneError;\n\npub trait Try {\n    type Ok;","sourceCodeStart":184,"sourceCodeEnd":220,"githubUrl":"https://github.com/embassy-rs/embassy/blob/463a07b963419a1bfe61d5d597c44acb810afb8b/embassy-rp/src/fmt.rs#L184-L220","documentation":"embassy-rp's `unwrap!` macro wraps a `Result`/`Option`-returning expression and panics with a debug dump of the error when it is `Err`/`None`, replacing plain `.unwrap()` to give better diagnostics in a `no_std`/defmt environment. Any embassy-rp internal or user code path using this macro on a failing expression produces this panic.","triggerScenarios":"Any `unwrap!(expr)` call in embassy-rp where the expression returns `Err(e)` (via `fmt::Try::into_result`), such as peripheral init, GPIO, SPI/I2C calls, or embedded-hal operations returning embedded-hal errors.","commonSituations":"Failed peripheral operations (e.g. SPI transfer error, I2C NACK) being force-unwrapped in driver internals; user code adopting the embassy-rp `unwrap!` macro on fallible HAL calls; version drift where a call that used to return a plain value now returns Result.","solutions":["Inspect the `{:?}` debug value in the panic to identify the inner error type and variant","Locate the failing call site from the stringified expression in the panic message","Handle the Result at the call site with `?`, `match`, or `map_err` instead of unwrapping","Fix the underlying hardware/configuration issue the inner error indicates (wrong pins, missing pull-ups, busy bus)"],"exampleFix":"// before\nlet byte = unwrap!(spi.blocking_read(&mut buf));\n// after\nlet byte = spi.blocking_read(&mut buf).map_err(|e| {\n    defmt::error!(\"spi read failed: {:?}\", e);\n    e\n})?;\n","handlingStrategy":"try-catch","validationCode":"fn unwrap_or_log<T, E: core::fmt::Debug>(r: Result<T, E>) -> Option<T> {\n    match r { Ok(t) => Some(t), Err(e) => { defmt::error!(\"op failed: {:?}\", e); None } }\n}\n","typeGuard":"fn is_ok<T, E>(r: &Result<T, E>) -> bool { r.is_ok() }\n","tryCatchPattern":null,"preventionTips":["Propagate HAL Results with ? instead of unwrapping","Log the Debug output of inner errors before any unwrap","Handle expected hardware errors (NACK, timeout) explicitly","Audit unwrap! usage when porting code between HAL versions"],"tags":["rust","embedded","rp2040","unwrap-panic","macro"],"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"}