vectordotdev/vector · error
named struct fields must always have an ident
Error message
named struct fields must always have an ident
What it means
`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.
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
Defensive patterns
Strategy: validation
Prevention
- 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
When it happens
Trigger: 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).
Common situations: 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.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- enums must always have a tagging mode
- `required_one_of` cannot be applied to a `#[serde(skip)]`…
- `required_one_of` cannot be applied to a…
- already found inputs
- can't run runner twice
AI-assisted analysis of vectordotdev/vector@bdb87aeaa4 (2026-09-16).
Data as JSON: /api/errors/db732f695a31769f.
Report an issue: GitHub.
Appendix: source
Thrown at lib/vector-config-macros/src/configurable.rs:275
let mut subschema = #spanned_generate_schema;
}
}
#[derive(Clone)]
struct RequiredOneOf {
group: String,
members: Vec<String>,
}
fn generate_named_struct_field(
container: &Container<'_>,
field: &Field<'_>,
required_one_of: Option<RequiredOneOf>,
sibling_keys: &[String],
) -> proc_macro2::TokenStream {
let field_name = field
.ident()
.expect("named struct fields must always have an ident");
let field_schema_ty = get_field_schema_ty(field);
let field_already_contained = format!(
"schema properties already contained entry for `{field_name}`, this should not occur"
);
let field_key = field.name();
let field_schema = generate_struct_field(field, sibling_keys);
// Inject docs::required_one_of and docs::required_one_of_group metadata so the CUE doc
// builder can render the mutual exclusivity constraint and its group name.
let inject_required_one_of = required_one_of.map(|RequiredOneOf { group, members }| {
let member_lits: Vec<syn::LitStr> = members
.iter()
.map(|m| syn::LitStr::new(m, proc_macro2::Span::call_site()))
.collect();
quote! {
if let Some(meta) = subschema.extensions.get_mut("_metadata") {
if let Some(obj) = meta.as_object_mut() {View on GitHub (pinned to bdb87aeaa4)