{"record":{"id":"781991b5875c607e","repo":"tracel-ai/burn","slug":"capture-tensor-operations-must-run-inside-captured","errorCode":null,"errorMessage":"capture tensor operations must run inside CaptureDevice::capture_scope","messagePattern":"capture tensor operations must run inside CaptureDevice::capture_scope","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"crates/burn-capture/src/capture.rs","lineNumber":349,"sourceCode":"///\n/// Capture clients are scope-specific: [`CaptureDevice::capture_scope`] creates the client and\n/// installs it with `register_scoped_client` before any tensor operations run. An unscoped client\n/// would have no lifecycle owner or completed graph boundary, so it is intentionally unsupported.\n#[derive(Clone)]\npub struct CaptureChannel;\n\nimpl RouterChannel for CaptureChannel {\n    type Device = CaptureDevice;\n    type Bridge = CaptureBridge;\n    type Client = CaptureClient;\n\n    fn name(_device: &Self::Device) -> String {\n        \"capture\".into()\n    }\n\n    fn init_client(_device: &Self::Device) -> Self::Client {\n        // `get_client` reaches this only when no capture scope registered its client first.\n        panic!(\"capture tensor operations must run inside CaptureDevice::capture_scope\")\n    }\n\n    fn get_tensor_handle(tensor: &TensorIr, client: &Self::Client) -> TensorData {\n        client\n            .state()\n            .lock()\n            .value(tensor.id)\n            .unwrap_or_else(|| panic!(\"capture tensor {} has no initialized value\", tensor.id))\n    }\n\n    fn register_tensor(\n        client: &Self::Client,\n        handle: TensorData,\n        _shape: Shape,\n        _dtype: DType,\n    ) -> RouterTensor<Self::Client> {\n        client.register_tensor_data(handle)\n    }","sourceCodeStart":331,"sourceCodeEnd":367,"githubUrl":"https://github.com/tracel-ai/burn/blob/d16f7ba2ed0d41408189384044cc886fb4c8f957/crates/burn-capture/src/capture.rs#L331-L367","documentation":"CaptureDevice requires that all tensor operations on its clients run inside `CaptureDevice::capture_scope`. When code obtains a client via `get_client` (e.g. during client initialization or lazy client creation) and no capture scope has registered a client, this panic fires. It is a misuse guard: the capture graph only exists while a scope is active.","triggerScenarios":"Calling any tensor operation on a CaptureDevice tensor outside of `device.capture_scope(...)`; constructing or lazily initializing a CaptureDevice client (init_client path) before entering a capture scope; holding a captured tensor beyond the scope and using it later.","commonSituations":"Creating capture tensors at module init time before the scope starts; storing captured tensors in a struct field and using them after `capture_scope` returns; mixing CaptureDevice with code paths that internally call `get_client` (e.g. lazy backend init).","solutions":["Wrap all tensor creation/usage for this device inside `CaptureDevice::capture_scope(|device| { ... })`.","Move module construction or client initialization into the capture scope closure.","Do not return capture-device tensors out of the scope; convert/extract results (e.g. into a tensor on a real backend) inside the scope."],"exampleFix":"// before\nlet tensor = Tensor::<CaptureDevice, 2>::ones([2, 2], &device);\ndevice.capture_scope(|_d| { /* ... */ });\n// after\ndevice.capture_scope(|device| {\n    let tensor = Tensor::<CaptureDevice, 2>::ones([2, 2], device);\n    // use tensor here\n});","handlingStrategy":"validation","validationCode":"// Enter the scope before creating any capture tensors\nlet result = device.capture_scope(|device| {\n    let t = Tensor::<CaptureDevice, 2>::ones([2, 2], device);\n    t.into_data() // extract results inside the scope\n});","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never construct CaptureDevice tensors outside capture_scope","Never leak captured tensors out of the closure; convert to data or a real-backend tensor inside","Initialize modules inside the capture scope if they lazily create tensors"],"tags":["rust","burn","graph-capture","panic"],"backgroundTag":"operation-outside-capture-scope","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"}