BoundaryML/baml · error · syn::Error

variant `{}` has more than one `#[axis(..)]`

Error message

variant `{}` has more than one `#[axis(..)]`

What it means

In `resolve_variant`, an enum variant may carry at most one `#[axis(..)]` attribute. A second one makes the axis identifier ambiguous, so the macro aborts at parse time. The non-axis attributes are collected separately and the first axis wins otherwise, but duplicates are hard errors.

Source

Thrown at baml_language/crates/baml_type_macros/src/parse.rs:398

            generics: master.generics,
            members: resolved_members,
            satellites: resolved_satellites,
            variants,
        })
    }
}

fn resolve_variant(
    variant: syn::Variant,
    axis_index: &impl Fn(&Ident) -> syn::Result<usize>,
) -> syn::Result<MVariant> {
    let span = variant.ident.span();
    let mut axis_ident: Option<Ident> = None;
    let mut attrs = Vec::new();
    for attr in variant.attrs {
        if attr.path().is_ident("axis") {
            if axis_ident.is_some() {
                return Err(syn::Error::new(
                    span,
                    format!(
                        "variant `{}` has more than one `#[axis(..)]`",
                        variant.ident
                    ),
                ));
            }
            axis_ident = Some(attr.parse_args_with(Ident::parse_any)?);
        } else {
            attrs.push(attr);
        }
    }
    let axis_ident = axis_ident.ok_or_else(|| {
        syn::Error::new(
            span,
            format!(
                "variant `{}` must declare exactly one `#[axis(..)]`",
                variant.ident

View on GitHub (pinned to bd85ce9dee)

Solutions

  1. Delete the duplicate `#[axis(..)]` attribute, keeping only one per variant.
  2. Merge the axis payloads into a single `#[axis(..)]` if both carried information.
  3. Rename the variant if the two axes were intended for distinct variants.

Example fix

// before
#[axis(Type)]
#[axis(Shape)]
Variant,
// after
#[axis(Type)]
Variant,
Defensive patterns

Strategy: validation

Validate before calling

// rustfmt/clippy side check or code review
// each variant's attrs must contain at most one #[axis(..)]

Prevention

When it happens

Trigger: Writing two `#[axis(..)]` attributes on the same variant of a derive-defined enum; `variant.attrs` contains more than one attribute whose path is `axis` while `axis_ident` is already `Some`.

Common situations: Copy-pasting variant definitions and forgetting to delete the original `#[axis(..)]`; merging branches that both added an axis attribute.

Related errors


AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12). Data as JSON: /api/errors/0c43ea6958573155. Report an issue: GitHub.