vectordotdev/vector · error · syn::Error

`required_one_of` is not supported on enum variant fields

Error message

`required_one_of` is not supported on enum variant fields

What it means

Compile-time error from `generate_named_enum_field` in vector-config-macros. Struct-style enum variants are represented as subschemas keyed by field name, but `required_one_of` groups are only wired up for named struct containers; putting one on a field inside an enum variant has no codegen path, so it is rejected to avoid silently ignored constraints.

Source

Thrown at lib/vector-config-macros/src/configurable.rs:841

    quote! {
        #(#mapped_custom_attributes)*
    }
}

fn get_field_schema_ty<'a>(field: &'a Field<'a>) -> &'a syn::Type {
    // If there's a delegated type being used for field (de)serialization, that's ultimately the type
    // we use to declare the schema, because we have to generate the schema for whatever type is
    // actually being (de)serialized, not the final type that the intermediate value ends up getting
    // converted to.
    //
    // Otherwise, we just use the actual field type.
    field.delegated_ty().unwrap_or_else(|| field.ty())
}

fn generate_named_enum_field(field: &Field<'_>) -> proc_macro2::TokenStream {
    if field.required_one_of().is_some() {
        return syn::Error::new(
            field.span(),
            "`required_one_of` is not supported on enum variant fields",
        )
        .to_compile_error();
    }
    let field_name = field.ident().expect("field should be named");
    let field_ty = field.ty();
    let field_already_contained = format!(
        "schema properties already contained entry for `{field_name}`, this should not occur"
    );
    let field_key = field.name().to_string();

    let field_schema = generate_struct_field(field);

    // Fields that have no default value are inherently required.  Unlike fields on a normal
    // struct, we can't derive a default value for an individual field because `serde`
    // doesn't allow even specifying a default value for an enum overall, only structs.
    let spanned_is_optional = quote_spanned! {field.span()=>

View on GitHub (pinned to 3708c39b12)

Solutions

  1. Move the fields into a nested named struct and put required_one_of there, then use that struct as the variant's payload
  2. Or express the constraint with separate enum variants, one per required field combination
  3. Or drop required_one_of and validate at deserialization time with a custom TryFrom

Example fix

// before
enum Auth { Key { #[configurable(required_one_of = ["k"])] key: Option<String> } }

// after
#[derive(Configurable)]
struct KeyAuth { #[configurable(required_one_of = ["key", "token"])] key: Option<String>, token: Option<String> }
enum Auth { Key(KeyAuth) }
Defensive patterns

Strategy: validation

Validate before calling

# CI gate: enum-variant usage fails at compile time
cargo check --workspace --all-targets

Prevention

When it happens

Trigger: `#[configurable(required_one_of(...))]` on a field of a struct variant: `enum E { V { #[configurable(required_one_of = ...)] field: T } }` where the enum derives Configurable.

Common situations: Trying to express 'one of these two fields must be set' inside a variant (e.g. alternative auth fields per variant) when the mechanism only exists at the named-struct level.

Related errors


AI-assisted analysis of vectordotdev/vector@3708c39b12 (2026-08-20). Data as JSON: /api/errors/a84bcd882796b328. Report an issue: GitHub.