zellij-org/zellij · error · anyhow::Error

failed to send message to channel: {:#?}

Error message

failed to send message to channel: {:#?}

What it means

Debug-mode variant of the ToAnyhow implementation for crossbeam/mpc SendError in zellij-utils/errors.rs. Sending a (T, ErrorContext) message failed because the receiving end of the channel was dropped — typically the owning thread exited via shutdown, disconnect, or a panic. In DEBUG_MODE the unsent message itself is pretty-printed into the error before the ErrorContext is attached, so you can see exactly which message could not be delivered.

Source

Thrown at zellij-utils/src/errors.rs:956

    }

    /// `SendError` doesn't satisfy `anyhow`s trait requirements due to `T` possibly being a
    /// `PluginInstruction` type, which wraps an `mpsc::Send` and isn't `Sync`. Due to this, in turn,
    /// the whole error type isn't `Sync` and doesn't work with `anyhow` (or pretty much any other
    /// error handling crate).
    ///
    /// Takes the `SendError` and creates an `anyhow` error type with the message that was sent
    /// (formatted as string), attaching the [`ErrorContext`] as anyhow context to it.
    impl<T: std::fmt::Debug, U> ToAnyhow<U>
        for Result<U, crate::channels::SendError<(T, ErrorContext)>>
    {
        fn to_anyhow(self) -> anyhow::Result<U> {
            match self {
                Ok(val) => anyhow::Ok(val),
                Err(e) => {
                    let (msg, context) = e.into_inner();
                    if *crate::consts::DEBUG_MODE.get().unwrap_or(&true) {
                        Err(anyhow::anyhow!(
                            "failed to send message to channel: {:#?}",
                            msg
                        ))
                        .with_context(|| context.to_string())
                    } else {
                        Err(anyhow::anyhow!("failed to send message to channel"))
                            .with_context(|| context.to_string())
                    }
                },
            }
        }
    }

    impl<U> ToAnyhow<U> for Result<U, std::sync::PoisonError<U>> {
        fn to_anyhow(self) -> anyhow::Result<U> {
            match self {
                Ok(val) => anyhow::Ok(val),
                Err(e) => {

View on GitHub (pinned to 98a0837077)

Solutions

  1. Look earlier in the logs for a panic or exit in the thread that owned the channel receiver — this error is almost always the symptom, not the cause
  2. Restart the zellij session (`zellij --new-session ...`) to rebuild the channel fabric
  3. Avoid force-killing the server while plugins are scheduling actions; use the quit action for graceful teardown
  4. Upgrade zellij if the receiver-thread panic is a known fixed bug; report with the panic backtrace if not

Example fix

// before
sender.send((msg, ErrorContext::new())).to_anyhow()?; // errors after receiver dies

// after: stop sending once the peer is gone
if !sender.is_connected_to_any_receiver() {
    log::warn!("dropping message, receiver gone");
    return Ok(());
}
sender.send((msg, ErrorContext::new())).to_anyhow()?;
Defensive patterns

Strategy: try-catch

Validate before calling

// before sending on a crossbeam bus sender
if !sender.is_connected_to_any_receiver() {
    // receiver thread is gone; sending would fail
    return Ok(());
}

Try / catch

use zellij_utils::errors::prelude::*;

if let Err(e) = sender.send((msg, ErrorContext::new())).to_anyhow() {
    log::warn!("dropping message, channel closed: {e:#}");
    // treat as termination of this emitter loop, do not propagate
    break;
}

Prevention

When it happens

Trigger: Calling .to_anyhow()? (directly or via the ? operator) on a channel send after the receiver thread has terminated: session teardown while another thread still emits actions, a panicked screen/router/os_input worker that owned the receiver, or a bus/IPC endpoint disconnecting mid-send.

Common situations: Zellij server shutting down while a plugin or scheduled action fires; a worker thread that panicked earlier (this error is the downstream symptom); killing the session process during heavy keybinding/plugin activity; races between client disconnect and pending input routing.

Related errors


AI-assisted analysis of zellij-org/zellij@98a0837077 (2026-08-16). Data as JSON: /api/errors/4b735172a91423eb. Report an issue: GitHub.