embassy-rs/embassy · error
unwrap of ` ` failed
Error message
unwrap of `{}` failed: {}: {:?} What it means
This is the context-carrying variant of embassy-net-wiznet's `unwrap!` macro (non-defmt build): `unwrap!(expr, "message", args...)`. When `expr` is `Err` or `None`, it panics printing the stringified expression, the caller-supplied context message, and the debug-formatted error value. The extra `format_args!` text comes from the call site to pinpoint which operation failed.
Solutions
- Read the context message in the panic output to locate the failing operation, then find that `unwrap!(..., "ctx")` call in embassy-net-wiznet sources.
- Fix the root cause: verify SPI wiring, clock speed, chip select, and that the W5500 is properly reset and powered.
- Handle the error path explicitly at the call site instead of unwrapping if failures are expected in your environment.
- Enable `defmt` logging to get better diagnostics on constrained targets.
Example fix
// before let reg = unwrap!(self.read_reg(Reg::PHYCFGR), "read phycfgr"); // after let reg = self.read_reg(Reg::PHYCFGR).map_err(|_| Error::Spi)?;
Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-check the operation the context label names, e.g. SPI bus:
if !self.spi_ok().await { return Err(Error::Spi); } Type guard
fn is_ok<T, E>(r: &Result<T, E>) -> bool { r.is_ok() } Try / catch
// Use a panic hook that records the context message (second field of the panic) to identify the failing subsystem, then perform a safe device reset.
Prevention
- Treat the panic's context message as the lead and audit that specific driver path.
- Stress-test SPI bus under EMI/long traces; add error retry at the board level.
- Keep embassy-net-wiznet and embassy-net versions in sync.
- Enable defmt for richer failure diagnostics.
When it happens
Trigger: Any call to `unwrap!(expr, "ctx", ...)` in the wiznet W5500 driver where `expr` yields `Err(e)` or `None` — the second panic arm at fmt.rs:197 fires only when the caller passed extra message arguments.
Common situations: Embedded firmware using the Wiznet Ethernet driver hits a failed SPI/queue/register operation while a context label (e.g. "spi transfer", "fifo read") is attached, usually during bring-up of new hardware or after a bus glitch.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- unwrap of ` ` failed
- unwrap of ` ` failed
- unwrap of ` ` failed
- unwrap of ` ` failed
- Can only take the executor once
AI-assisted analysis of embassy-rs/embassy@463a07b963 (2026-09-10).
Data as JSON: /api/errors/84bc622943d20ed9.
Report an issue: GitHub.
Appendix: source
Thrown at embassy-net-wiznet/src/fmt.rs:197
};
}
#[cfg(not(feature = "defmt"))]
#[collapse_debuginfo(yes)]
macro_rules! unwrap {
($arg:expr) => {
match $crate::fmt::Try::into_result($arg) {
::core::result::Result::Ok(t) => t,
::core::result::Result::Err(e) => {
::core::panic!("unwrap of `{}` failed: {:?}", ::core::stringify!($arg), e);
}
}
};
($arg:expr, $($msg:expr),+ $(,)? ) => {
match $crate::fmt::Try::into_result($arg) {
::core::result::Result::Ok(t) => t,
::core::result::Result::Err(e) => {
::core::panic!("unwrap of `{}` failed: {}: {:?}", ::core::stringify!($arg), ::core::format_args!($($msg,)*), e);
}
}
}
}
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub struct NoneError;
pub trait Try {
type Ok;
type Error;
fn into_result(self) -> Result<Self::Ok, Self::Error>;
}
impl<T> Try for Option<T> {
type Ok = T;
type Error = NoneError;
View on GitHub (pinned to 463a07b963)