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
- Ensure client and server use compatible versions of burn-communication/burn-remote so message enums match.
- Verify the server actually streams TensorData on the 'data' subprotocol channel, not control messages.
- 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
- Pin matching burn versions on client and server
- Only send TensorData on the 'data' channel
- Log and handle unexpected variants instead of assuming
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
- Received a message that wasn't a tensor request! {msg:?}
- capture tensor operations must run inside CaptureDevice::cap
- capture tensor {} has no initialized value
- seeding is not supported during graph capture
- capture graph {graph_id:?} was not registered
AI-assisted analysis of tracel-ai/burn@d16f7ba2ed (2026-09-05).
Data as JSON: /api/errors/55d81c9131719a39.
Report an issue: GitHub.