vectordotdev/vector · error · syn::Error
`required_one_of` cannot be applied to a `#[serde(skip)]` fi
Error message
`required_one_of` cannot be applied to a `#[serde(skip)]` field
What it means
Compile-time error from `build_named_struct_generate_schema_fn` in vector-config-macros. Vector's `required_one_of` helper generates a schema-level `oneOf` requirement over serde field names, so every participating field must appear in the serialized/deserialized object. `#[serde(skip)]` removes the field from both, making the requirement unsatisfiable; the macro scans ALL fields (even non-visible ones) specifically to catch this.
Source
Thrown at lib/vector-config-macros/src/configurable.rs:370
quote! {
{
#field_schema
subschemas.push(subschema);
}
}
}
fn build_named_struct_generate_schema_fn(
container: &Container<'_>,
fields: &[Field<'_>],
) -> proc_macro2::TokenStream {
// Validate required_one_of usage before building groups.
// Scan ALL fields (including non-visible) so #[serde(skip)] fields are caught too.
for field in fields.iter() {
if field.required_one_of().is_some() {
if !field.visible() {
return syn::Error::new(
field.span(),
"`required_one_of` cannot be applied to a `#[serde(skip)]` field",
)
.to_compile_error();
}
if field.flatten() {
return syn::Error::new(
field.span(),
"`required_one_of` cannot be applied to a `#[serde(flatten)]` field",
)
.to_compile_error();
}
if !is_option_type(field.ty())
&& field.default_value().is_none()
&& container.default_value().is_none()
{
return syn::Error::new(
field.span(),View on GitHub (pinned to 3708c39b12)
Solutions
- Remove the `#[configurable(required_one_of(...))]` attribute from the skipped field
- Or remove `#[serde(skip)]` if the field is actually user-configurable and must be part of the group
- Move the group membership to a visible field that carries the same semantic choice
Example fix
// before #[configurable(required_one_of = ["strategy"])] #[serde(skip)] pub strategy_hint: Strategy, // after // (drop one of the two attributes; keep required_one_of only on deserialized fields) pub strategy: Option<Strategy>,
Defensive patterns
Strategy: validation
Validate before calling
# CI gate: attribute conflicts fail at compile time cargo check --workspace --all-targets
Prevention
- Audit required_one_of members and remove the attribute when a field gains #[serde(skip)]
- Remember the macro checks skipped fields too — conflicts always surface at compile time
When it happens
Trigger: Applying both `#[serde(skip)]` and `#[configurable(required_one_of(...))]` to the same field of a `#[derive(Configurable)]` named struct.
Common situations: Refactoring a config struct where a field became internal (skip) but its old `required_one_of` attribute was left behind; merging configs where attributes accumulated.
Related errors
- `required_one_of` cannot be applied to a `#[serde(flatten)]`
- `required_one_of` cannot be applied to a `#[serde(skip_deser
- `required_one_of` requires the field to be optional; use `Op
- `required_one_of` is not supported on tuple struct fields
- `required_one_of` is not supported on newtype struct fields
AI-assisted analysis of vectordotdev/vector@3708c39b12 (2026-08-20).
Data as JSON: /api/errors/62b4785637cd1da9.
Report an issue: GitHub.