{"record":{"id":"db732f695a31769f","repo":"vectordotdev/vector","slug":"named-struct-fields-must-always-have-an-ident","errorCode":null,"errorMessage":"named struct fields must always have an ident","messagePattern":"named struct fields must always have an ident","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"lib/vector-config-macros/src/configurable.rs","lineNumber":275,"sourceCode":"        let mut subschema = #spanned_generate_schema;\n    }\n}\n\n#[derive(Clone)]\nstruct RequiredOneOf {\n    group: String,\n    members: Vec<String>,\n}\n\nfn generate_named_struct_field(\n    container: &Container<'_>,\n    field: &Field<'_>,\n    required_one_of: Option<RequiredOneOf>,\n    sibling_keys: &[String],\n) -> proc_macro2::TokenStream {\n    let field_name = field\n        .ident()\n        .expect(\"named struct fields must always have an ident\");\n    let field_schema_ty = get_field_schema_ty(field);\n    let field_already_contained = format!(\n        \"schema properties already contained entry for `{field_name}`, this should not occur\"\n    );\n    let field_key = field.name();\n\n    let field_schema = generate_struct_field(field, sibling_keys);\n\n    // Inject docs::required_one_of and docs::required_one_of_group metadata so the CUE doc\n    // builder can render the mutual exclusivity constraint and its group name.\n    let inject_required_one_of = required_one_of.map(|RequiredOneOf { group, members }| {\n        let member_lits: Vec<syn::LitStr> = members\n            .iter()\n            .map(|m| syn::LitStr::new(m, proc_macro2::Span::call_site()))\n            .collect();\n        quote! {\n            if let Some(meta) = subschema.extensions.get_mut(\"_metadata\") {\n                if let Some(obj) = meta.as_object_mut() {","sourceCodeStart":257,"sourceCodeEnd":293,"githubUrl":"https://github.com/vectordotdev/vector/blob/bdb87aeaa4c4ff27c0ba643c1c77b21bf2ef4013/lib/vector-config-macros/src/configurable.rs#L257-L293","documentation":"`generate_named_struct_field` unwraps `field.ident()` with an expect because it is only invoked for named-field structs, where serde always provides an identifier. A None here means the derive generated a call for a field that is not a named field — a violation of the macro's internal dispatch invariants.","triggerScenarios":"Expanding `#[configurable]` on a named struct when `build_named_struct_generate_schema_fn` processes a `Field` whose ident is None (i.e. a tuple/newtype field reached the named-struct code path).","commonSituations":"Unreachable in normal use; seen only with proc-macro bugs, hand-written token streams passed into the macro helpers, or dependency version mismatches after upgrades.","solutions":["Verify the struct uses named fields (this path is not for tuple structs); use the appropriate derive path for newtype/tuple structs","Align vector-config-macros and serde_derive versions and rebuild (cargo clean)","If reproducible, minimize the failing struct definition and file an issue"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["Only apply #[configurable] to structs with named fields via this path","Keep macro crates and serde_derive versions consistent","Minimize and report any struct that triggers this panic"],"tags":["proc-macro","serde","schema","panic","internal-invariant"],"backgroundTag":"internal-invariant-violation","analyzedSha":"bdb87aeaa4c4ff27c0ba643c1c77b21bf2ef4013","analyzedAt":"2026-09-16T02:53:35.741Z","contentChangedAt":"2026-09-16T02:53:35.741Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}