{"record":{"id":"e7bae2f3826747b1","repo":"embassy-rs/embassy","slug":"unwrap-of-failed-e7bae2","errorCode":null,"errorMessage":"unwrap of `{}` failed: {:?}","messagePattern":"unwrap of `(.+?)` failed: (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"embassy-net/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-net/src/fmt.rs#L184-L220","documentation":"This panic originates from embassy-net's internal `unwrap!` macro (the non-defmt variant) defined in src/fmt.rs. It converts its argument via `fmt::Try::into_result` (works for both `Result` and `Option`) and panics with the stringified expression plus the debug-formatted error when the value is `Err` or `None`. It marks a fail-fast on an operation the stack implementation treats as unrecoverable/assumed-infallible.","triggerScenarios":"Any `unwrap!(expr)` inside embassy-net where `expr` is an `Err(e)` or `None` — e.g. internal channel/queue operations, socket-state lookups, or mDNS/DHCP-related unwraps during network stack execution.","commonSituations":"Rust embedded (embassy) firmware using the embassy-net TCP/UDP stack: a resource queue returned None (capacity exhausted or closed) or an internal operation failed, panicking the firmware task instead of returning an error.","solutions":["Locate the failing call: the panic message prints the stringified expression; search embassy-net/src for that `unwrap!(...)` site.","Address the root cause — commonly resource capacity issues (increase packet/socket buffer counts in `Config`) or a closed channel/socket being used.","Enable the `defmt` feature for `defmt::unwrap!` and better embedded logging.","Patch the call site to return an error (e.g. `Error::ConnectionReset` style) if the failure is environment-dependent."],"exampleFix":"// before: internal unwrap panics on closed channel\nlet pkt = unwrap!(self.rx_chan.receive().await);\n// after: return an error instead of panicking\nlet pkt = self.rx_chan.receive().await.map_err(|_| Error::ConnectionReset)?;","handlingStrategy":"validation","validationCode":"// Size resources generously so internal unwraps never see empty/full queues:\nlet resources = embassy_net::StackResources::<8>::new(); // > expected concurrent sockets\n// And check socket state before use:\nif socket.state() == embassy_net::tcp::State::Closed { /* reopen */ }","typeGuard":"fn has_capacity<T>(q: &embassy_sync::channel::Channel<'_, T, N>, n: usize) -> bool { q.try_send(unsafe { core::mem::MaybeUninit::zeroed().assume_init() }).is_ok() } // prefer explicit capacity accounting","tryCatchPattern":"// Install a panic hook to log the unwrap expression and task context, then restart the network task (or soft-reset) since panics abort in embedded targets.","preventionTips":["Allocate more entries in StackResources / packet buffers than peak concurrency requires.","Never use sockets or channels after close/teardown; check state first.","Run the stack in CI with logging (defmt) to catch queue exhaustion early.","Pin embassy-net versions and read changelogs for unwrap-site changes."],"tags":["embedded","rust","panic","unwrap","networking"],"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"}