vectordotdev/vector · error

tuple variants should be rejected during AST parsing

Error message

tuple variants should be rejected during AST parsing

What it means

The `Configurable` derive macro rejects tuple-style enum variants when generating schemas for tagged enums. Tuple variants are expected to have been detected and rejected earlier, during AST parsing of the derive input, so encountering `Style::Tuple` at schema-generation time (`generate_enum_variant_schema`) means the parser invariant was broken. The panic is a defensive assertion, not a user-fixable configuration issue at this stage.

Solutions

  1. Convert the tuple variant to a struct variant with named fields
  2. Wrap the payload in a struct so the variant becomes a struct/newtype variant that supports internal tagging
  3. Remove the tag-based representation requirement (e.g. use a different enum representation) if tuple variants are required

Example fix

// before
#[configurable(tag = "type")]
enum E { Name(String) }
// after
#[configurable(tag = "type")]
enum E { Name { value: String } }
Defensive patterns

Strategy: validation

Validate before calling

// Reject tuple variants in tagged enums before compiling:
fn has_tuple_variants(enum_name: &str, variant_styles: &[&str]) -> bool {
    debug_assert!(
        !variant_styles.iter().any(|s| *s == "tuple"),
        "enum {} uses tuple variants, unsupported for tagged Configurable enums",
        enum_name
    );
    variant_styles.iter().any(|s| *s == "tuple")
}

Prevention

When it happens

Trigger: Schema generation reaches `Style::Tuple` in `generate_enum_variant_schema` (lib/vector-config-macros/src/configurable.rs:1144) — i.e. an enum like `enum E { V(String) }` used in a context that requires a tagged/adjacently-tagged schema, and AST parsing failed to reject it first.

Common situations: Declaring a newtype/tuple variant such as `Variant(Vec<u8>)` or `Variant(InnerStruct)` on an internally-tagged enum; refactoring a struct variant into a tuple variant while keeping the tag attribute.

Related errors


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

Appendix: source

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

                let tag_field = quote! {
                    {
                        if let Some(_) = properties.insert(#tag.to_string(), #tag_schema) {
                            panic!(#tag_already_contained);
                        }

                        if !required.insert(#tag.to_string()) {
                            panic!(#tag_already_contained);
                        }
                    }
                };
                generate_enum_struct_named_variant_schema(
                    variant,
                    Some(tag_field),
                    Some(tag),
                    false,
                )
            }
            Style::Tuple => panic!("tuple variants should be rejected during AST parsing"),
            Style::Newtype => {
                // We have to delegate viability to `serde`, essentially, because using internal tagging for a newtype
                // variant is only possible when the inner field is a struct or map, and we can't access that type of
                // information here, which is why `serde` does it at compile-time.

                // As such, we generate the schema for the single field, like we would normally do for a newtype
                // variant, and then we follow the struct flattening logic where we layer on our tag field schema on the
                // schema of the wrapped field... and since it has to be a struct or map to be valid for `serde`, that
                // means it will also be an object schema in both cases, which means our flattening logic will be
                // correct if the caller is doing The Right Thing (tm).
                let newtype_schema = generate_enum_newtype_struct_variant_schema(variant, false);
                let tag_schema = generate_enum_variant_tag_schema(variant);

                quote! {
                    let tag_schema = ::vector_config::schema::generate_internal_tagged_variant_schema(#tag.to_string(), #tag_schema);
                    let mut flattened_subschemas = ::std::vec::Vec::new();
                    flattened_subschemas.push(tag_schema);

View on GitHub (pinned to bdb87aeaa4)