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

When generating the schema for a named enum variant, `generate_named_enum_field` rejects `required_one_of` on variant fields. One-of semantics on enum variant fields are not supported in the generated config schema, so the macro produces a compile error.

Solutions

  1. Remove `required_one_of` from the enum variant field.
  2. Split the variant into multiple variants, each representing one of the alternatives.
  3. Use a nested named struct (where `required_one_of` is supported) as the variant's payload type.

Example fix

// before
#[configurable]
enum Source {
    A { #[configurable(required_one_of = ["x"])] x: u64, y: u64 },
}

// after
#[configurable]
enum Source {
    A(NestedOneOf),
}
Defensive patterns

Strategy: validation

Validate before calling

// ensure enum variant fields carry no required_one_of before applying #[configurable]

Prevention

When it happens

Trigger: Declaring an enum with `#[configurable]` where a struct-like variant's named field is annotated with `required_one_of`.

Common situations: Trying to encode 'variant A requires one of fields x or y' inside an enum used as a config component; users attempt this when modeling mutually alternative config shapes.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of vectordotdev/vector@bdb87aeaa4 (2026-09-16). Data as JSON: /api/errors/a84bcd882796b328. Report an issue: GitHub.

Appendix: source

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

        .filter(|field| field.visible() && !field.flatten())
        .map(|field| field.name().to_string())
        .collect()
}

fn collision_sibling_keys(fields: &[Field<'_>], enclosing_tag: Option<&str>) -> Vec<String> {
    let mut names = unflattened_serialized_names(fields);
    if let Some(tag) = enclosing_tag {
        names.push(tag.to_owned());
    }
    names
}

fn generate_named_enum_field(
    field: &Field<'_>,
    sibling_keys: &[String],
) -> 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, sibling_keys);

    // 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 bdb87aeaa4)