{"record":{"id":"788b874fc063e93c","repo":"PyO3/pyo3","slug":"named-field-has-an-identifier","errorCode":null,"errorMessage":"named field has an identifier","messagePattern":"named field has an identifier","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pyo3-macros-backend/src/pyclass.rs","lineNumber":699,"sourceCode":"            |variant: &'a mut syn::Variant| -> syn::Result<PyClassEnumVariant<'a>> {\n                use syn::Fields;\n                let ident = &variant.ident;\n                let options = EnumVariantPyO3Options::take_pyo3_options(&mut variant.attrs)?;\n\n                let variant = match &variant.fields {\n                    Fields::Unit => {\n                        bail_spanned!(variant.span() => format!(\n                            \"Unit variant `{ident}` is not yet supported in a complex enum\\n\\\n                            = help: change to an empty tuple variant instead: `{ident}()`\\n\\\n                            = note: the enum is complex because of non-unit variant `{witness}`\",\n                            ident=ident, witness=witness))\n                    }\n                    Fields::Named(fields) => {\n                        let fields = fields\n                            .named\n                            .iter()\n                            .map(|field| PyClassEnumVariantNamedField {\n                                ident: field.ident.as_ref().expect(\"named field has an identifier\"),\n                                ty: &field.ty,\n                                attrs: &field.attrs,\n                                span: field.span(),\n                            })\n                            .collect();\n\n                        PyClassEnumVariant::Struct(PyClassEnumStructVariant {\n                            ident,\n                            fields,\n                            options,\n                            attrs: variant.attrs.clone(),\n                        })\n                    }\n                    Fields::Unnamed(types) => {\n                        let fields = types\n                            .unnamed\n                            .iter()\n                            .map(|field| PyClassEnumVariantUnnamedField {","sourceCodeStart":681,"sourceCodeEnd":717,"githubUrl":"https://github.com/PyO3/pyo3/blob/ac9b6899d348be4d54614d060dea53a645a12e36/pyo3-macros-backend/src/pyclass.rs#L681-L717","documentation":"When extracting named fields of a #[pyclass] enum variant, the macro unwraps each field's identifier with expect. As with struct fields, syn guarantees named fields carry identifiers, so this panic signals a corrupted AST or wrong code path (e.g. tuple/unit variants reaching the named-field branch).","triggerScenarios":"Internal path violation: a variant with tuple or unit fields processed by the Fields::Named branch; not triggerable from valid user code with #[pyclass] enums.","commonSituations":"Patched macro backends, syn version mismatches, or third-party attribute macros that rewrite variant fields before pyo3 sees them.","solutions":["Use an unmodified pyo3/syn combination from the same supported versions.","Ensure any intervening macro passes preserve field identifiers on named fields.","Route non-named variants to their proper match arms before this code runs.","Report a minimal repro to pyo3 if valid code panics."],"exampleFix":"// before (variant reaching the wrong branch)\nenum E { Tuple(u32) } // processed as named-fields\n// after\nenum E { Struct { value: u32 } } // matches Fields::Named branch","handlingStrategy":"validation","validationCode":"// Only route Fields::Named variants through the named-field extractor\nmatches!(variant.fields, syn::Fields::Named(_));","typeGuard":"fn has_named_fields(v: &syn::Variant) -> bool {\n    matches!(v.fields, syn::Fields::Named(_))\n}","tryCatchPattern":null,"preventionTips":["Match all three syn::Fields arms explicitly in enum-variant handling.","Preserve field identifiers in any AST-rewriting passes that run before pyo3.","Pin a supported syn version compatible with your pyo3 release."],"tags":["pyo3","proc-macro","enum","internal-invariant"],"backgroundTag":"internal-invariant-panic","analyzedSha":"ac9b6899d348be4d54614d060dea53a645a12e36","analyzedAt":"2026-09-05T09:20:35.319Z","contentChangedAt":"2026-09-05T09:20:35.319Z","schemaVersion":2},"datasetVersion":"2026-09-12T12:17:11.808Z"}