BoundaryML/baml · error · syn::Error
variant `{}` requires an explicit discriminant to stabilize
Error message
variant `{}` requires an explicit discriminant to stabilize its Borsh tag What it means
Type-family variants must carry an explicit `u8` integer discriminant so the Borsh serialization tag is stable. `resolve_variant` raises this error when the discriminant expression is absent (the `None` arm). A present but non-u8-literal discriminant gets the separate 'type-family variants require an explicit u8 integer discriminant' error.
Source
Thrown at baml_language/crates/baml_type_macros/src/parse.rs:433
"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",
));
}
None => {
return Err(syn::Error::new(
span,
format!(
"variant `{}` requires an explicit discriminant to stabilize its Borsh tag",
variant.ident
),
));
}
};
// A variant need not carry a `TyAttr`: a template-only leaf (`TypeArgRef`)
// is pure structure with no streaming metadata. The generated
// `attr()`/`with_attr()` accessors fall back to `TyAttr::EMPTY` / identity
// for them (see `emit::attr_arm`). `has_attr` records which case applies so
// the accessor arms don't need to re-derive it.
let has_attr = carries_ty_attr(&variant.fields);
Ok(MVariant {
attrs,
ident: variant.ident,
fields: variant.fields,View on GitHub (pinned to bd85ce9dee)
Solutions
- Add an explicit integer discriminant to the variant, e.g. `Variant = 4`.
- Pick an unused u8 value consistent with the other variants' numbering.
- Never reuse a discriminant already assigned to another variant.
Example fix
// before
#[axis(Shape)]
Variant { x: u32 },
// after
#[axis(Shape)]
Variant = 5 { x: u32 }, Defensive patterns
Strategy: validation
Validate before calling
// every variant needs an explicit u8 discriminant
// enum TypeFamily { A = 0, B = 1, /* ... */ } Prevention
- Always write `= N` discriminants; never rely on implicit numbering
- Assign new variants the next free u8 and record the mapping
- Remember discriminants are wire tags — treat changes as breaking
When it happens
Trigger: Declaring a variant with `#[axis(..)]` but no explicit discriminant like `= 3`; the discriminant match on the variant's expr returns `None`.
Common situations: Adding a variant and omitting the discriminant because plain Rust enums allow implicit numbering; implicit tags would break wire compatibility if variants are reordered.
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
- invalid package interface: {message}
- unknown axis `{name}`
- unknown family member `{name}`
- interned member `{name}` cannot be another member's child
- the master member cannot be interned: the master is the plai
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/3e495a76d6563470.
Report an issue: GitHub.