{"record":{"id":"046a9e92b8ad0390","repo":"tracel-ai/burn","slug":"service-call-failed-046a9e","errorCode":null,"errorMessage":"Service call failed","messagePattern":"Service call failed","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/burn-remote/src/client/runner.rs","lineNumber":42,"sourceCode":"        let stream_id = StreamId::current();\n        // Device ids in the op's payload are *client* remote device ids; rewrite them to\n        // server-local device indices the server can resolve to its own backend devices. Applies\n        // to every op — only ops that actually carry device ids are rewritten.\n        let op = self.resolve_devices(op);\n        self.handle.submit(move |s| s.register_op(stream_id, op));\n    }\n\n    fn read_tensor_async(\n        &self,\n        tensor: burn_ir::TensorIr,\n    ) -> DynFut<Result<TensorData, ExecutionError>> {\n        // Issue the request synchronously so ordering is preserved relative to subsequent\n        // submissions; the returned future just awaits the server's response.\n        let stream_id = StreamId::current();\n        let rx = self\n            .handle\n            .submit_blocking(move |s| s.read_tensor(stream_id, tensor))\n            .expect(\"Service call failed\");\n\n        Box::pin(async move {\n            match rx.await {\n                Ok(TaskResponseContent::ReadTensor(res)) => res,\n                Ok(_) => panic!(\"Invalid response type for ReadTensor\"),\n                Err(e) => Err(ExecutionError::Generic {\n                    reason: format!(\"Failed to read tensor: {e:?}\"),\n                    backtrace: BackTrace::capture(),\n                }),\n            }\n        })\n    }\n\n    fn register_tensor_data(&self, data: TensorData) -> RouterTensor<Self> {\n        let shape = data.shape.clone();\n        let dtype = data.dtype;\n        let id = service::new_tensor_id();\n","sourceCodeStart":24,"sourceCodeEnd":60,"githubUrl":"https://github.com/tracel-ai/burn/blob/d16f7ba2ed0d41408189384044cc886fb4c8f957/crates/burn-remote/src/client/runner.rs#L24-L60","documentation":"`read_tensor_async` synchronously submits a `read_tensor` request via `handle.submit_blocking(...)` and unwraps the returned oneshot receiver with `expect(\"Service call failed\")`. If the submission cannot reach the service (runner shut down, channel closed) the call returns `None` and panics. Note the subsequent `rx.await` handles real execution errors as `ExecutionError` — this expect only fires for local service-channel failure.","triggerScenarios":"Calling tensor read (via the async backend's `read_tensor`) after the remote service runner has terminated, or submitting on a handle whose channel is closed, so `submit_blocking` returns `None` instead of a response receiver.","commonSituations":"Reading results after the remote server crashed or connection was torn down; using a client/handle beyond shutdown; WASM suspension killing the service; holding cloned backend past client drop.","solutions":["Recreate the remote client/backend after the service dies, then re-issue the read.","Keep the service/runner alive until all in-flight tensor reads complete.","Use `sync`/connection health checks before reads in long-running sessions.","Catch the panic at a boundary (e.g. `catch_unwind`) if shutdown races are unavoidable, and reconnect."],"exampleFix":"// before\nlet tensor = backend.read_tensor(desc).await; // panics if service dead\n// after\n// ensure client is alive or recreate:\nlet backend = get_or_recreate_backend(&config);\nlet tensor = backend.read_tensor(desc).await;","handlingStrategy":"try-catch","validationCode":"// guard long sessions: verify connectivity before reads\n// e.g. issue a cheap sync/heartbeat; on failure recreate the backend\nif !backend_healthy(&handle) { let backend = recreate_backend(&config)?; }","typeGuard":null,"tryCatchPattern":"let tensor = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {\n    backend_clone.read_tensor(desc)\n}));\nif tensor.is_err() { /* recreate backend, re-issue read */ }","preventionTips":["Keep the remote service alive until all reads complete","Sync and drain pending reads before shutting the client down","Avoid cloned backends outliving the owning client","Recreate the backend after any server crash before further reads"],"tags":["rust","panic","remote","tensor","ipc","shutdown"],"backgroundTag":"service-channel-closed","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"}