tracel-ai/burn · error

Message should have been TensorData

Error message

Message should have been TensorData

What it means

When downloading a tensor over the remote WebSocket 'data' channel, the client expects every message to deserialize as `ExternalCommMessage::Tensor`. If deserialization succeeds but the variant differs, this panic fires — the peer sent an unexpected message type on the data channel, indicating a protocol mismatch between client and server.

Source

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

        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 => {
                // Open a new WebSocket connection to the address
                let stream = match P::Client::connect(address.clone(), "data").await {

View on GitHub (pinned to d16f7ba2ed)

Solutions

  1. Ensure client and server use compatible versions of burn-communication/burn-remote so message enums match.
  2. Verify the server actually streams TensorData on the 'data' subprotocol channel, not control messages.
  3. Capture the debug output in the panic message ({msg:?}) to identify the unexpected variant and fix the peer.
Defensive patterns

Strategy: type-guard

Validate before calling

// On the client side, validate the variant instead of panicking
if let ExternalCommMessage::Tensor(data) = msg { /* use data */ } else { log::warn!("unexpected data-channel message"); }

Type guard

fn as_tensor(msg: ExternalCommMessage) -> Option<TensorData> {
    match msg { ExternalCommMessage::Tensor(d) => Some(d), _ => None }
}

Try / catch

// Wrap download in a task and convert panic to error
let res = tokio::spawn(async move { download(...).await }).await;
match res { Ok(Ok(data)) => data, _ => Err(ProtocolMismatch) }

Prevention

When it happens

Trigger: A burn-remote server (or proxy) responding on the 'data' channel with a non-Tensor message (e.g. TensorRequest, error, or a message from a different burn version); connecting a client to a server running incompatible burn-communication protocol.

Common situations: Version skew between client and server burn crates; a misconfigured intermediary that forwards control-channel messages onto the data channel; two peers both acting as downloaders and answering each other's TensorRequests.

Related errors


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