BoundaryML/baml · error · syn::Error
Rust unions are not supported for this derive macro.
Error message
Rust unions are not supported for this derive macro.
What it means
Compile-time error from the `BamlSerde` derive macro: Rust `union` declarations are not supported at all. Rust unions lack safe field access and do not fit the serde data model the macro targets. Emitted by `derive_serde` for `Data::Union`.
Solutions
- Remove `BamlSerde` from the union
- Wrap the union in a struct and manually implement serialization over its bytes
- Convert the union to a tagged enum if the discriminant is known
Example fix
// before
#[derive(BamlSerde)]
union U { int: i32, float: f32 }
// after
#[derive(BamlSerde)]
#[serde(untagged)]
#[baml(union = true)]
enum U { Int(i32), Float(f32) } Defensive patterns
Strategy: type-guard
Prevention
- Never derive serde-like macros on Rust unions
- Model variant data as tagged/untagged enums instead of unions
- Keep raw unions isolated in FFI modules without derive macros
When it happens
Trigger: Applying `#[derive(BamlSerde)]` to a `union` declaration, e.g. `#[derive(BamlSerde)] union U { a: i32, b: f32 }`.
Common situations: FFI code that defines raw unions and mistakenly applies BamlSerde expecting serialization support.
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
- BamlSerde cannot be derived for enums, use…
- BamlSerde cannot be derived for structs, use…
- Failed to deserialize value
- Failed to find in union
- Failed to serialize request result
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/4012289ffbe147ce.
Report an issue: GitHub.
Appendix: source
Thrown at languages/rust/baml-macros/src/baml_serde.rs:22
use crate::shared::{ContainerAttrs, VariantAttrs};
pub(crate) fn derive_serde(input: &DeriveInput) -> Result<TokenStream> {
let container_attrs = ContainerAttrs::from_attrs(&input.attrs)?;
match &input.data {
Data::Struct(..) => Err(syn::Error::new(
Span::call_site(),
"BamlSerde cannot be derived for structs, use `#[serde(flatten)]` on dynamic instead.",
)),
Data::Enum(data_enum) if container_attrs.union => {
derive_serde_union(data_enum, &input.ident)
}
Data::Enum(..) => Err(syn::Error::new(
Span::call_site(),
"BamlSerde cannot be derived for enums, use `#[serde(untagged)]` on dynamic instead.",
)),
Data::Union(..) => Err(syn::Error::new(
Span::call_site(),
"Rust unions are not supported for this derive macro.",
)),
}
}
fn derive_serde_union(data: &DataEnum, ident: &Ident) -> Result<TokenStream> {
let name = ident.to_string();
let mut literal_serde = Vec::new();
for variant in &data.variants {
let variant_attrs = VariantAttrs::from_attrs(&variant.attrs)?;
let variant_ident = &variant.ident;
if let Some(ref literal_string) = variant_attrs.literal_string {
literal_serde.push(quote! {
#[allow(non_snake_case)]View on GitHub (pinned to bd85ce9dee)