{"record":{"id":"f403679ffeaee712","repo":"tracel-ai/burn","slug":"only-float-tensors-may-use-an-autodiff-primitive-f40367","errorCode":null,"errorMessage":"only float tensors may use an autodiff primitive","messagePattern":"only float tensors may use an autodiff primitive","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/burn-backend-extension/src/routing.rs","lineNumber":772,"sourceCode":"    if autodiff {\n        let target = ir::with_backend(ty, quote!(#backend_alias));\n        let context = quote!(#dispatch_root::DispatchAutodiffContext);\n        quote! {\n            let #name = <#target as #extension_trait<#backend_alias>>::map_from_dispatch(#name, |__tensor| {\n                let __input_context = __tensor.autodiff;\n                match __tensor.kind {\n                    #dispatch_kind::Autodiff(inner) => {\n                        let #context::Enabled(_) = __input_context else {\n                            panic!(\"an autodiff float primitive must have an enabled autodiff context\")\n                        };\n                        let tensor = match *inner {\n                            #dispatch_kind::#backend(tensor) => tensor,\n                            #[allow(unreachable_patterns)]\n                            _ => #mismatch,\n                        };\n                        match tensor {\n                            #backend_tensor::Autodiff(tensor) => #backend_tensor::Float(tensor),\n                            _ => panic!(\"only float tensors may use an autodiff primitive\"),\n                        }\n                    }\n                    #dispatch_kind::#backend(tensor) => match tensor {\n                        #backend_tensor::Float(tensor) => {\n                            let #context::Disabled = __input_context else {\n                                panic!(\"an enabled float tensor must use an autodiff primitive\")\n                            };\n                            #backend_tensor::Float(\n                                <#backend_alias as #autodiff_trait>::from_inner(tensor)\n                            )\n                        }\n                        #backend_tensor::Int(tensor) => #backend_tensor::Int(tensor),\n                        #backend_tensor::Bool(tensor) => #backend_tensor::Bool(tensor),\n                        #backend_tensor::Quantized(tensor) => #backend_tensor::Quantized(tensor),\n                        #backend_tensor::Autodiff(_) => {\n                            panic!(\"autodiff float input reached concrete dispatch\")\n                        }\n                    },","sourceCodeStart":754,"sourceCodeEnd":790,"githubUrl":"https://github.com/tracel-ai/burn/blob/d16f7ba2ed0d41408189384044cc886fb4c8f957/crates/burn-backend-extension/src/routing.rs#L754-L790","documentation":"Generated by extract_extension (autodiff path): within an `Autodiff` dispatch variant, the inner `BackendTensor` must itself be the `Autodiff` variant (i.e. a float tensor under gradient tracking). The match panics when the inner tensor is Int, Bool, Quantized, or otherwise not an autodiff float — only float tensors can carry autodiff state.","triggerScenarios":"Wrapping a non-float tensor (Int indices, Bool mask, Quantized weights) in the Autodiff dispatch kind and passing it to an autodiff-routed extension input.","commonSituations":"Generic helper that wraps every input in `Autodiff(...)` regardless of dtype; tensor kind changed to Int/Bool upstream while routing metadata still says autodiff float; quantized models routed through autodiff primitives.","solutions":["Pass non-float tensors as their concrete kind (not wrapped in Autodiff)","Verify upstream code did not change the tensor kind; keep autodiff wrapping only for float tensors","Adjust the routed signature so the input is declared with its actual kind"],"exampleFix":"// before\nDispatchTensorKind::Autodiff(Box::new(DispatchTensorKind::Candle(BackendTensor::Int(t)))) // panics\n// after\nDispatchTensorKind::Candle(BackendTensor::Int(t)) // pass Int directly","handlingStrategy":"type-guard","validationCode":"if let DispatchTensorKind::Autodiff(inner) = &t.kind { assert!(matches!(**inner_inner_is_autodiff_float(inner)), \"only float tensors may be autodiff-wrapped\"); }","typeGuard":"fn is_autodiff_float(t: &DispatchTensor) -> bool { matches!(&t.kind, DispatchTensorKind::Autodiff(inner) if matches!(inner.as_ref(), DispatchTensorKind::Target(BackendTensor::Autodiff(_)))) }","tryCatchPattern":null,"preventionTips":["Only wrap float tensors in the Autodiff kind","Keep Int/Bool/Quantized tensors in their concrete kinds","Review generic wrappers that blanket-wrap inputs in Autodiff"],"tags":["burn","autodiff","tensor-kind"],"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"}