vectordotdev/vector · error · syn::Error
`required_one_of` cannot be applied to a `#[serde(flatten)]`
Error message
`required_one_of` cannot be applied to a `#[serde(flatten)]` field
What it means
Compile-time error from `build_named_struct_generate_schema_fn`. A `#[serde(flatten)]` field is merged into the parent object at deserialization time, so it has no top-level key of its own; a `oneOf` requirement keyed on the flattened field's name could never match. The macro rejects the combination up front.
Source
Thrown at lib/vector-config-macros/src/configurable.rs:377
}
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(),
"`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(),View on GitHub (pinned to 3708c39b12)
Solutions
- Move `required_one_of` to the concrete, non-flattened fields that actually represent the alternatives
- Or stop flattening that field so it appears as a named key and can participate in the group
- If the flattened inner type itself needs the constraint, put required_one_of on the inner struct's own fields
Example fix
// before #[configurable(required_one_of = ["tls"])] #[serde(flatten)] pub tls: TlsConfig, // after // put the group on the real alternative fields instead pub tls_enabled: Option<bool>, pub tls_files: Option<TlsFiles>,
Defensive patterns
Strategy: validation
Validate before calling
# CI gate: flatten conflicts fail at compile time cargo check --workspace --all-targets
Prevention
- Keep required_one_of groups on concrete named fields, never on #[serde(flatten)] fields
- Put constraints on the inner struct's own fields when flattening shared config
When it happens
Trigger: Applying `#[configurable(required_one_of(...))]` to a field that also carries `#[serde(flatten)]` in a Configurable-derived named struct.
Common situations: Config structs that flatten a shared sub-config (e.g. a common TLS or proxy block) and then try to include the flattened field in a required-one-of group during schema work.
Related errors
- `required_one_of` cannot be applied to a `#[serde(skip)]` fi
- `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/fbff8eac86908f1c.
Report an issue: GitHub.