tracel-ai/burn · error

Can deserialize messages from the websocket.

Error message

Can deserialize messages from the websocket.

What it means

This panic occurs in download_tensor when deserializing a websocket message with rmp_serde (MessagePack) into ExternalCommMessage fails, or when the deserialized message is not the Tensor variant. It indicates protocol desynchronization: the peer sent bytes that are not a valid tensor response — a different burn/protocol version, corrupt frame, or a foreign message type on this connection.

Source

Thrown at crates/burn-communication/src/external_comm.rs:167

        // Send the download request with the download id
        let bytes: bytes::Bytes =
            rmp_serde::to_vec(&ExternalCommMessage::TensorRequest(transfer_id))
                .unwrap()
                .into();
        stream
            .send(Message::new(bytes))
            .await
            .expect("Failed to send download id");

        if let Ok(msg) = stream.recv().await {
            let Some(msg) = msg else {
                log::warn!("Received None message from the websocket, closing connection.");
                return None;
            };

            let ExternalCommMessage::Tensor(data) = rmp_serde::from_slice(&msg.data)
                .expect("Can deserialize messages from the websocket.")
            else {
                panic!("Message should have been TensorData")
            };
            return Some(data);
        }
        log::warn!("Closed connection");
        None
    }

    /// Get the WebSocket stream for the given address, or create a new one if it doesn't exist.
    async fn get_data_stream(
        &self,
        address: Address,
    ) -> Arc<Mutex<<P::Client as ProtocolClient>::Channel>> {
        let mut streams = self.channels.lock().await;
        match streams.get(&address) {
            Some(stream) => stream.clone(),
            None => {

View on GitHub (pinned to d16f7ba2ed)

Solutions

  1. Ensure all peers run the same burn/burn-communication version so ExternalCommMessage encodes identically.
  2. Log and return None (treat as failed download) instead of panicking on unexpected message types.
  3. Inspect the raw bytes of the failing frame to confirm whether it is corrupt or a different message variant.
  4. Check for proxies/middleware that could alter binary websocket frames (disable permessage-deflate mismatches, ensure binary framing).

Example fix

// before
let ExternalCommMessage::Tensor(data) = rmp_serde::from_slice(&msg.data)
    .expect("Can deserialize messages from the websocket.")
else { panic!("Message should have been TensorData") };
// after
match rmp_serde::from_slice::<ExternalCommMessage>(&msg.data) {
    Ok(ExternalCommMessage::Tensor(data)) => return Some(data),
    Ok(other) => log::warn!("unexpected message {other:?}"),
    Err(e) => log::warn!("deserialization failed: {e}"),
}
return None;
Defensive patterns

Strategy: type-guard

Type guard

fn as_tensor_msg(bytes: &[u8]) -> Option<ExternalCommMessage> {
    match rmp_serde::from_slice::<ExternalCommMessage>(bytes) {
        Ok(ExternalCommMessage::Tensor(d)) => Some(ExternalCommMessage::Tensor(d)),
        _ => None,
    }
}

Try / catch

let Some(ExternalCommMessage::Tensor(data)) = as_tensor_msg(&msg.data) else {
    log::warn!("non-tensor/corrupt frame received");
    return None;
};

Prevention

When it happens

Trigger: Receiving a message from a peer running a different burn-communication version with a changed ExternalCommMessage enum; the data channel delivering interleaved/misrouted frames; truncated or corrupted MessagePack payloads on a flaky connection.

Common situations: Mixed-version cluster where nodes were upgraded independently; middleware/proxy mangling binary frames; two servers sharing a websocket channel with mismatched message expectations.

Related errors


AI-assisted analysis of tracel-ai/burn@d16f7ba2ed (2026-09-05). Data as JSON: /api/errors/1aa99bb7954aa0cf. Report an issue: GitHub.