{"record":{"id":"db9a828be0685339","repo":"tracel-ai/burn","slug":"can-serialize-remotemessage-init","errorCode":null,"errorMessage":"Can serialize RemoteMessage::Init","messagePattern":"Can serialize RemoteMessage::Init","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/burn-remote/src/client/service.rs","lineNumber":170,"sourceCode":"        executor\n            .block_on(open_channels(endpoint))\n            .unwrap_or_else(|err: String| panic!(\"{err}\"))\n    }\n\n    /// Send the session-init handshake on both streams and wait for the device settings the\n    /// server replies with on the response stream. Both streams carry the same `Vec<RemoteMessage>`\n    /// wire format; the handshake is just a single-element batch.\n    async fn handshake_async(\n        request: &mut SubmitChannel,\n        response: &mut ResponseChannel,\n        endpoint: &RemoteEndpoint,\n        session_id: SessionId,\n        device_index: u32,\n    ) -> (DeviceSettings, u32) {\n        let init_bytes: bytes::Bytes = rmp_serde::to_vec(&vec![RemoteMessage::Init(\n            SessionInit::new(session_id, device_index, endpoint.authorization().to_vec()),\n        )])\n        .expect(\"Can serialize RemoteMessage::Init\")\n        .into();\n\n        let result: Result<(DeviceSettings, u32), String> = async {\n            request.send(init_bytes).await?;\n\n            let msg = response\n                .recv()\n                .await?\n                .expect(\"Server disconnected during initialization\");\n            let reply: TaskResponse =\n                rmp_serde::from_slice(&msg).expect(\"Can deserialize init handshake payload\");\n\n            match reply.content {\n                TaskResponseContent::Init(SessionInfo {\n                    version,\n                    settings,\n                    device_count,\n                    ..","sourceCodeStart":152,"sourceCodeEnd":188,"githubUrl":"https://github.com/tracel-ai/burn/blob/d16f7ba2ed0d41408189384044cc886fb4c8f957/crates/burn-remote/src/client/service.rs#L152-L188","documentation":"This panic fires during the client-to-server handshake when MessagePack serialization of the single-element `RemoteMessage::Init` batch fails. The library treats this as an invariant that can never legitimately fail — `SessionInit` contains only serializable plain data (session id, device index, auth token bytes) — so the result is unwrapped with an expect rather than propagated. Hitting it indicates a broken build or a corrupted/incompatible rmp_serde dependency, not a user mistake.","triggerScenarios":"Only when rmp_serde::to_vec fails to serialize `vec![RemoteMessage::Init(SessionInit::new(...))]` during `handshake_async`; in practice this never happens with valid data and would require a dependency mismatch or a non-serializable field introduced by a custom fork.","commonSituations":"Mixing incompatible versions of `rmp-serde` / `bytes` via cargo dependency resolution; using a patched fork of burn-remote that added non-serializable fields to `SessionInit` or `RemoteMessage`; exotic no_std/target builds where a serde impl is misconfigured.","solutions":["Run `cargo update -p rmp-serde` (or align rmp-serde versions with `cargo tree -d -p rmp-serde`) so the dependency matches what burn-remote was built against.","Verify you are on an unmodified, matching version of burn/burn-remote — if you forked it, check any fields you added to SessionInit or RemoteMessage are serde-serializable.","Rebuild from scratch (`cargo clean && cargo build`) to rule out a stale build artifact.","If reproducible, file a bug with burn including the rmp_serde error details."],"exampleFix":"// before (fork with non-serializable field)\nstruct SessionInit { id: SessionId, device: u32, auth: Vec<u8>, custom: Box<dyn Any> }\n// after\n#[derive(serde::Serialize, serde::Deserialize)]\nstruct SessionInit { id: SessionId, device: u32, auth: Vec<u8> }","handlingStrategy":"try-catch","validationCode":"// Panics are not catchable via Result; validate dependency setup instead:\n// cargo tree -d -p rmp-serde  (must show exactly one version)\n// Also verify SessionInit fields in any fork derive Serialize/Deserialize.","typeGuard":null,"tryCatchPattern":"// This expect panics; catch with std::panic::catch_unwind only around service init:\nlet result = std::panic::catch_unwind(|| RemoteService::init(...));\nif result.is_err() { eprintln!(\"burn-remote init failed (serialization invariant)\"); }","preventionTips":["Keep rmp-serde versions unified across the workspace (cargo tree -d).","Avoid patching burn-remote wire types; if you must, keep them plain serde-serializable data.","Rebuild cleanly after upgrading burn.","Run handshake in a child/isolated process in critical deployments so a panic cannot take down the host."],"tags":["serialization","msgpack","panic","burn-remote"],"backgroundTag":"msgpack-serialization-panic","analyzedSha":"d16f7ba2ed0d41408189384044cc886fb4c8f957","analyzedAt":"2026-09-05T13:19:14.260Z","contentChangedAt":"2026-09-05T13:19:14.260Z","schemaVersion":2},"datasetVersion":"2026-09-12T17:17:11.597Z"}