vectordotdev/vector · error · syn::Error
`required_one_of` cannot be applied to a `#[serde(skip_deser
Error message
`required_one_of` cannot be applied to a `#[serde(skip_deserializing)]` field; users cannot set its value
What it means
Compile-time error from `build_named_struct_generate_schema_fn`. `#[serde(skip_deserializing)]` means the field's value is never taken from user config (it is populated by code after deserialization), so users cannot satisfy a `required_one_of` group through it. The macro rejects this combination explicitly.
Source
Thrown at lib/vector-config-macros/src/configurable.rs:394
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();
for field in fields.iter().filter(|f| f.visible()) {
if let Some(group) = field.required_one_of() {
groups
.entry(group.to_string())
.or_default()
.push(field.name().to_string());
}View on GitHub (pinned to 3708c39b12)
Solutions
- Remove `required_one_of` from the skip_deserializing field
- Redesign the group so it only contains fields users can actually set in config
- If the field is user-settable after all, remove `#[serde(skip_deserializing)]` and make it optional
Example fix
// before #[configurable(required_one_of = ["auth"])] #[serde(skip_deserializing)] pub auth: AuthState, // after #[serde(skip_deserializing)] pub auth: AuthState, // excluded from the group; group uses user-set fields
Defensive patterns
Strategy: validation
Validate before calling
# CI gate: skip_deserializing conflicts fail at compile time cargo check --workspace --all-targets
Prevention
- required_one_of only makes sense on fields users can set in config
- Keep internal/skip_deserializing fields out of schema constraint groups
When it happens
Trigger: A field annotated with both `#[serde(skip_deserializing)]` (e.g. computed/derived fields like a client handle or resolved endpoint) and `#[configurable(required_one_of(...))]`.
Common situations: Config structs that carry runtime-resolved state alongside user options; during a schema-attributes refactor the group attribute is left on the now-internal field.
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` 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/688a4975bc2e465a.
Report an issue: GitHub.