BoundaryML/baml · error · syn::Error

variant `{}` must declare exactly one `#[axis(..)]`

Error message

variant `{}` must declare exactly one `#[axis(..)]`

What it means

Every variant of a derive-defined type-family enum must declare exactly one `#[axis(..)]` attribute. `resolve_variant` collects axis idents and, if none was found, raises this error. The axis is required for the macro to classify the variant.

Source

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

    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
            ),
        )
    })?;
    let axis = axis_index(&axis_ident)?;
    let discriminant = match variant.discriminant.as_ref().map(|(_, expr)| expr) {
        Some(syn::Expr::Lit(syn::ExprLit {
            lit: syn::Lit::Int(value),
            ..
        })) => value.base10_parse::<u8>()?,
        Some(expr) => {
            return Err(syn::Error::new_spanned(
                expr,
                "type-family variants require an explicit u8 integer discriminant",
            ));

View on GitHub (pinned to bd85ce9dee)

Solutions

  1. Add a `#[axis(SomeAxisIdent)]` attribute to the variant.
  2. Check sibling variants for the correct axis naming pattern and copy it.
  3. If the variant belongs to no axis, move it to a separate enum outside the derive.

Example fix

// before
Variant { field: u32 },
// after
#[axis(Type)]
Variant { field: u32 },
Defensive patterns

Strategy: validation

Validate before calling

// before deriving, confirm each variant has an axis
// variant list must satisfy: every variant carries exactly one #[axis(..)]

Prevention

When it happens

Trigger: Declaring a variant with no `#[axis(..)]` attribute; `axis_ident` is `None` after the attribute loop, triggering the `ok_or_else` error.

Common situations: Adding a new variant to an existing type-family enum and forgetting the attribute; removing an attribute during refactoring.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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