{"record":{"id":"b710f2b327d4be92","repo":"tracel-ai/burn","slug":"an-enabled-float-tensor-must-use-an-autodiff-primi","errorCode":null,"errorMessage":"an enabled float tensor must use an autodiff primitive","messagePattern":"an enabled float tensor must use an autodiff primitive","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/burn-backend-extension/src/routing.rs","lineNumber":541,"sourceCode":"    let name = &input.name;\n    let selected = format_ident!(\"__burn_selected\");\n    let dispatch_root = &extraction.paths.dispatch_root;\n    let backend_alias = &extraction.paths.backend_alias;\n    let context = quote!(#dispatch_root::DispatchAutodiffContext);\n    assert!(\n        kind == TensorKind::Float || !autodiff_variant,\n        \"only a float input can directly select an autodiff primitive\"\n    );\n    let validate_context = if kind == TensorKind::Float && autodiff_variant {\n        quote! {\n            let #context::Enabled(_) = __burn_selected_context else {\n                panic!(\"an autodiff float primitive must have an enabled autodiff context\")\n            };\n        }\n    } else if kind == TensorKind::Float {\n        quote! {\n            let #context::Disabled = __burn_selected_context else {\n                panic!(\"an enabled float tensor must use an autodiff primitive\")\n            };\n        }\n    } else {\n        TokenStream::new()\n    };\n\n    if kind == TensorKind::Float && extraction.autodiff && !autodiff_variant {\n        let autodiff_trait = &extraction.paths.autodiff_trait;\n        if borrowed {\n            let lifted = format_ident!(\"__lifted_{name}\");\n            quote! {\n                #validate_context\n                let #lifted = <#backend_alias as #autodiff_trait>::from_inner(#selected.as_float().clone());\n                let #name = &#lifted;\n            }\n        } else {\n            quote! {\n                #validate_context","sourceCodeStart":523,"sourceCodeEnd":559,"githubUrl":"https://github.com/tracel-ai/burn/blob/d16f7ba2ed0d41408189384044cc886fb4c8f957/crates/burn-backend-extension/src/routing.rs#L523-L559","documentation":"Generated by extract_selected_input for float tensor inputs routed to a non-autodiff primitive: the macro requires DispatchAutodiffContext::Disabled. If the context is Enabled (the tensor carries autodiff state), the operation panics because an enabled float tensor must go through the autodiff primitive, not the concrete one.","triggerScenarios":"Calling an operation whose selected float input resolves to the concrete backend primitive while the tensor's autodiff context is Enabled — e.g. passing a require_grad()/autodiff-wrapped tensor into a path compiled for the plain backend.","commonSituations":"Passing gradient-tracking tensors into inference-only ops; mixing autodiff-enabled and disabled tensors in one dispatch call; toggling require_grad on a tensor then routing it through a concrete-backend extension.","solutions":["Detach/stop tracking gradients on the tensor (e.g. .detach()) before passing it to the concrete dispatch path","Or route through the autodiff-enabled operation variant instead","Keep Enabled/Disabled tensor contexts consistent per operation call"],"exampleFix":"// before\nlet out = op(tensor.require_grad()); // Enabled context into concrete path\n// after\nlet out = op(tensor.detach()); // Disabled context for concrete dispatch","handlingStrategy":"type-guard","validationCode":"fn require_disabled_context(t: &DispatchTensor) -> Result<(), String> {\n    match t.autodiff {\n        DispatchAutodiffContext::Disabled => Ok(()),\n        _ => Err(\"enabled float tensor must use the autodiff primitive; detach first\".into()),\n    }\n}","typeGuard":"fn is_grad_disabled(t: &DispatchTensor) -> bool {\n    matches!(t.autodiff, DispatchAutodiffContext::Disabled)\n}","tryCatchPattern":"let out = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| op(&tensor)))\n    .map_err(|_| \"tensor has gradient tracking; call .detach() or use the autodiff variant\".to_string())?","preventionTips":["Call .detach() on training tensors before inference-only dispatch calls","Separate training and inference code paths explicitly","Never mix Enabled and Disabled tensors in one operation"],"tags":["rust","autodiff","gradient","proc-macro"],"backgroundTag":"autodiff-context-mismatch","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"}