embassy-rs/embassy · error

unwrap of ` ` failed

Error message

unwrap of `{}` failed: {}: {:?}

What it means

Variant of embassy's `unwrap!` macro that accepts extra message arguments: `unwrap!(expr, "context {}", x)`. When the expression yields Err (or None), it panics with the expression text, the user-supplied context, and the Debug-formatted error. As with the plain form, the root cause is the inner Err value surfaced by `Try::into_result`.

Solutions

  1. Read both the expression text and the extra context message in the panic output to locate the failing subsystem
  2. Inspect the Debug-formatted error value for the concrete cause
  3. Replace the macro call with explicit error handling (match/? ) for that call site
  4. Validate the arguments passed at that call site (pins, buffers, enums) against the driver's documented requirements

Example fix

// before
let res = unwrap!(init_peripheral(cfg), "init failed for {}", name);
// after
let res = match init_peripheral(cfg) {
    Ok(r) => r,
    Err(e) => {
        defmt::error!("init failed for {}: {:?}", name, e);
        return Err(e);
    }
};
Defensive patterns

Strategy: try-catch

Try / catch

// Replace unwrap!(expr, ctx...) with explicit handling:
// match op() {
//     Ok(v) => v,
//     Err(e) => { defmt::error!("{}: {:?}", ctx, e); return Err(e); }
// }

Prevention

When it happens

Trigger: Any call site using `unwrap!(expr, msg...)` where expr returns Err/None — the extra arguments are diagnostic context only; the failure is produced by the same underlying driver/peripheral errors as the one-argument form (e.g. failed peripheral init, DMA setup, or channel send).

Common situations: Same as the plain unwrap: invalid peripheral setup, wrong buffer sizes or alignment, dropped sender on an ipc/channel, invalid enum values for the chip variant — with the extra context identifying the subsystem that failed.

Related errors


AI-assisted analysis of embassy-rs/embassy@463a07b963 (2026-09-10). Data as JSON: /api/errors/321911b5edfcc7e7. Report an issue: GitHub.

Appendix: source

Thrown at embassy-nrf/src/fmt.rs:210

    };
}

#[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)