vectordotdev/vector · error · syn::Error
`required_one_of` requires the field to be optional; use `Op
Error message
`required_one_of` requires the field to be optional; use `Option<T>` or add `#[serde(default)]`
What it means
Compile-time error from `build_named_struct_generate_schema_fn`. A field in a `required_one_of` group may legitimately be absent (the group only requires ONE of its members), so each member must be optional: `Option<T>`, a field-level `#[serde(default)]`, or a container-level `#[serde(default)]`. If none of those hold, a missing group member could never deserialize and the macro rejects it.
Source
Thrown at lib/vector-config-macros/src/configurable.rs:387
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(),
"`required_one_of` requires the field to be optional; use `Option<T>` or add `#[serde(default)]`",
)
.to_compile_error();
}
if field.skip_deserializing() {
return syn::Error::new(
field.span(),
"`required_one_of` cannot be applied to a `#[serde(skip_deserializing)]` field; users cannot set its value",
)
.to_compile_error();
}
}
}
// Collect required_one_of groups at macro-expansion time: group_name -> [serde field names].
let mut groups: std::collections::BTreeMap<String, Vec<String>> =
std::collections::BTreeMap::new();View on GitHub (pinned to 3708c39b12)
Solutions
- Wrap the field in `Option<T>`: `pub b: Option<B>`
- Or add `#[serde(default)]` to the field so omission deserializes to Default
- Or add `#[serde(default)]` on the whole struct (container default) if all fields can default
Example fix
// before #[configurable(required_one_of = ["api_key", "credentials_path"])] pub credentials_path: PathBuf, // after #[configurable(required_one_of = ["api_key", "credentials_path"])] pub credentials_path: Option<PathBuf>,
Defensive patterns
Strategy: validation
Validate before calling
# CI gate: non-optional group members fail at compile time cargo check --workspace --all-targets
Prevention
- Make every required_one_of member Option<T> or add #[serde(default)]
- Remember container-level #[serde(default)] on the struct also satisfies the check
When it happens
Trigger: `#[configurable(required_one_of = ["a", "b"])]` on a plain `pub b: B` field (not Option) in a struct with no field or container default.
Common situations: Porting hand-written `#[serde(deny_unknown_fields)]`-style validation to the new required_one_of mechanism and forgetting that group members must be individually omittable.
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
- expected a string literal for the {component_type} name (i.e
- component name must be non-empty
AI-assisted analysis of vectordotdev/vector@3708c39b12 (2026-08-20).
Data as JSON: /api/errors/a7bfd026454c5bca.
Report an issue: GitHub.