BloopAI/vibe-kanban · error

Relay yamux session error: {e}

Error message

Relay yamux session error: {e}

What it means

In the same select! loop, session.next() can yield Some(Err(e)) where e is a yamux protocol/session error (stream reset, invalid frame, connection broken). The code maps that error into 'Relay yamux session error: {e}'. It signals the multiplexed session is corrupt or the transport failed mid-stream.

Source

Thrown at crates/relay-tunnel-core/src/client.rs:66

    let ws_io = tungstenite_ws_stream_io(ws_stream);
    let mut session = Session::new_client(ws_io, yamux_config());
    let mut control = session.control();

    tracing::debug!("Relay control channel connected");

    let shutdown = config.shutdown;
    let local_addr = config.local_addr;

    loop {
        tokio::select! {
            _ = shutdown.cancelled() => {
                control.close().await;
                return Ok(());
            }
            inbound = session.next() => {
                let stream = inbound
                    .ok_or_else(|| anyhow::anyhow!("Relay control channel closed"))?
                    .map_err(|e| anyhow::anyhow!("Relay yamux session error: {e}"))?;

                tokio::spawn(async move {
                    if let Err(error) = handle_inbound_stream(stream, local_addr).await {
                        tracing::warn!(?error, "Relay stream handling failed");
                    }
                });
            }
        }
    }
}

async fn handle_inbound_stream(
    stream: tokio_yamux::StreamHandle,
    local_addr: SocketAddr,
) -> anyhow::Result<()> {
    let io = TokioIo::new(stream);

    server_http1::Builder::new()

View on GitHub (pinned to 4deb7eca8f)

Solutions

  1. Reconnect the relay client with exponential backoff; the session is not recoverable once yamux errors out.
  2. Inspect the wrapped '{e}' to distinguish transport drops (reconnect) from protocol bugs (fix version mismatch).
  3. Enable yamux keepalives and shorter idle timeouts so dead connections are detected and re-established promptly.
  4. Check relay server logs around the same timestamp for the peer-side error.
Defensive patterns

Strategy: retry

Try / catch

match start_relay(...).await {
    Err(e) if e.to_string().contains("Relay yamux session error") => {
        tracing::warn!(?e, "yamux session broke; reconnecting");
        backoff_retry(|| start_relay(...)).await?;
    }
    other => other?,
}

Prevention

When it happens

Trigger: Underlying WebSocket to the relay breaks mid-session, yamux frame corruption/protocol violation, stream resets, or the remote abruptly resets the TCP connection carrying the multiplexed session.

Common situations: Unstable networks (mobile, hotel Wi-Fi) dropping long-lived tunnels; firewalls/NAT killing idle connections; relay server under memory pressure resetting streams; yamux version mismatches between client and server.

Related errors


AI-assisted analysis of BloopAI/vibe-kanban@4deb7eca8f (2026-08-29). Data as JSON: /api/errors/c65c5c68fe684598. Report an issue: GitHub.