{"record":{"id":"85fa71b526fe1ed4","repo":"tracel-ai/burn","slug":"can-t-register-manually-a-tensor-on-a-remote-chann","errorCode":null,"errorMessage":"Can't register manually a tensor on a remote channel.","messagePattern":"Can't register manually a tensor on a remote channel\\.","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/burn-remote/src/client/channel.rs","lineNumber":42,"sourceCode":"    }\n\n    fn get_tensor_handle(tensor: &TensorIr, client: &Self::Client) -> RemoteTensorHandle {\n        RemoteTensorHandle {\n            client: client.clone(),\n            tensor: tensor.clone(),\n        }\n    }\n\n    fn register_tensor(\n        _client: &Self::Client,\n        _handle: RemoteTensorHandle,\n        _shape: Shape,\n        _dtype: burn_backend::DType,\n    ) -> RouterTensor<Self::Client> {\n        // This function is normally only used to move a tensor from a device to another.\n        //\n        // In other words, to change the client.\n        panic!(\"Can't register manually a tensor on a remote channel.\");\n    }\n\n    fn change_client_backend(\n        tensor: RouterTensor<Self::Client>,\n        target_device: &Self::Device, // target device\n    ) -> RouterTensor<Self::Client> {\n        // Get tensor handle from current client\n        let original_client = tensor.client.clone();\n        let desc = tensor.into_ir();\n        let handle = Self::get_tensor_handle(&desc, &original_client);\n\n        let handle = handle.change_backend(target_device);\n\n        let id = handle.tensor.id;\n\n        let target_client = get_client::<Self>(target_device);\n        let router_tensor: RouterTensor<RemoteClient> =\n            RouterTensor::new(id, handle.tensor.shape, handle.tensor.dtype, target_client);","sourceCodeStart":24,"sourceCodeEnd":60,"githubUrl":"https://github.com/tracel-ai/burn/blob/d16f7ba2ed0d41408189384044cc886fb4c8f957/crates/burn-remote/src/client/channel.rs#L24-L60","documentation":"burn-remote's RegisterOperationChannel::register_tensor unconditionally panics: remote channels cannot manually register a tensor. Tensor registration is only meaningful for moving a tensor between local clients/devices; in the remote setting the tensor already lives server-side, so the operation is rejected. Use change_client_backend to move a RouterTensor to a different client instead.","triggerScenarios":"Calling register_tensor directly on a burn-remote client channel, e.g. attempting to re-home a RouterTensor across remote clients or calling low-level register APIs on tensors fetched from a remote compute server.","commonSituations":"Trying to migrate a tensor between remote devices; porting local multi-device code to the remote backend; custom code that assumes the local register_tensor contract holds for remote channels.","solutions":["Use change_client_backend (the TensorHandle-based path) to move a RouterTensor to the target device/client instead of register_tensor.","Perform the tensor transfer server-side (on the remote worker) and only send back the resulting handle.","If you need local registration semantics, execute that portion of code on a local backend, not a remote channel."],"exampleFix":"// before\nlet tensor = router_client.register(tensor, shape, dtype); // panics on remote channel\n// after\nlet tensor = RouterTensor::change_client_backend(tensor, &target_device); // re-homes across clients","handlingStrategy":"try-catch","validationCode":"// cannot be caught at type level; avoid calling register_tensor on remote channels.\n// detect remote backend via marker if you have one:\nfn is_remote_channel<C: burn_router::RegisterOperationChannel>(_: &C) -> bool {\n    std::any::TypeId::of::<C>() == std::any::TypeId::of::<burn_remote::client::RemoteChannel>()\n}","typeGuard":null,"tryCatchPattern":"// burn-remote panics rather than returning Result; route around it:\nlet result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {\n    channel.register(tensor, &shape, dtype)\n}));\nmatch result {\n    Ok(t) => t,\n    Err(_) => RouterTensor::change_client_backend(tensor, &target_device), // supported path\n}","preventionTips":["Never call register_tensor on remote channels; use change_client_backend to re-home tensors.","Centralize cross-client tensor transfers in one helper so the remote-unsafe call can't leak in.","Keep device-to-device moves server-side when using burn-remote; only ship handles to the client.","Add a code-review/CI check forbidding register_tensor in code paths behind the remote backend."],"tags":["rust","panic","remote","distributed","tensor-registration"],"backgroundTag":"remote-channel-unsupported-operation","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"}