vectordotdev/vector · error · syn::Error
`required_one_of` is not supported on newtype struct fields
Error message
`required_one_of` is not supported on newtype struct fields
What it means
Compile-time error from `build_newtype_struct_generate_schema_fn`. A newtype struct (`struct Wrapper(T)`) is transparent in serde — it serializes as the inner value directly, with no object key for the single field — so `required_one_of`, which keys on field names, cannot apply. The macro rejects it before generating the schema function.
Source
Thrown at lib/vector-config-macros/src/configurable.rs:554
// Don't map this field if it's marked to be skipped for both serialization and deserialization.
.filter(|field| field.visible())
.map(generate_tuple_struct_field);
quote! {
fn generate_schema(schema_gen: &::std::cell::RefCell<::vector_config::schema::SchemaGenerator>) -> std::result::Result<::vector_config::schema::SchemaObject, ::vector_config::GenerateError> {
let mut subschemas = ::std::collections::Vec::new();
#(#mapped_fields)*
Ok(::vector_config::schema::generate_tuple_schema(&subschemas))
}
}
}
fn build_newtype_struct_generate_schema_fn(fields: &[Field<'_>]) -> proc_macro2::TokenStream {
for field in fields.iter() {
if field.required_one_of().is_some() {
return syn::Error::new(
field.span(),
"`required_one_of` is not supported on newtype struct fields",
)
.to_compile_error();
}
}
// Map the fields normally, but we should end up with a single field at the end.
let mut mapped_fields = fields
.iter()
// Don't map this field if it's marked to be skipped for both serialization and deserialization.
.filter(|field| field.visible())
.map(generate_struct_field)
.collect::<Vec<_>>();
if mapped_fields.len() != 1 {
panic!("newtype structs should never have more than one field");
}View on GitHub (pinned to 3708c39b12)
Solutions
- Remove the `required_one_of` attribute from the newtype field
- Or change the wrapper to a named struct with one named, optional field and put the group there
Example fix
// before
struct Wrapper(#[configurable(required_one_of = ["x"])] Inner);
// after
struct Wrapper {
#[configurable(required_one_of = ["x", "y"])]
inner: Option<Inner>,
} Defensive patterns
Strategy: validation
Validate before calling
# CI gate: unsupported newtype usage fails at compile time cargo check --workspace --all-targets
Prevention
- Newtype wrappers are transparent in serde — no field keys, no name-keyed constraints
- Move the constraint to a named struct inside the wrapper if needed
When it happens
Trigger: `#[derive(Configurable)]` on a newtype struct whose single field has `#[configurable(required_one_of(...))]`.
Common situations: Wrapping an existing config type in a newtype (e.g. for the newtype pattern or type safety) while keeping attributes that only make sense on named-struct fields.
Related errors
- `required_one_of` cannot be applied to a `#[serde(skip)]` fi
- `required_one_of` cannot be applied to a `#[serde(flatten)]`
- `required_one_of` cannot be applied to a `#[serde(skip_deser
- `required_one_of` is not supported on tuple struct fields
- `required_one_of` is not supported on enum variant fields
AI-assisted analysis of vectordotdev/vector@3708c39b12 (2026-08-20).
Data as JSON: /api/errors/81324a790aede998.
Report an issue: GitHub.