BoundaryML/baml · error · BamlError
type error: expected {expected}, got {got}
Error message
type error: expected {expected}, got {got} What it means
BamlError::TypeCheck signals an expected runtime type mismatch in the Rust BAML bindings: a BamlValue had a different type than required. The FullTypeName trait supplies the descriptive "got" value, rendering as "type error: expected <X>, got <Y>".
Source
Thrown at languages/rust/baml/src/error.rs:14
use std::collections::HashMap;
/// BAML runtime errors
///
/// Note: This is intentionally minimal. Expand with specific variants
/// (`InitError`, `CallError`, etc.) once the core functionality works.
#[derive(Debug, thiserror::Error, Clone)]
pub enum BamlError {
/// Internal/unexpected errors - bugs in BAML that should never happen
#[error("internal error: {0}")]
Internal(String),
/// Type check errors - expected runtime failures (type mismatches)
#[error("type error: expected {expected}, got {got}")]
TypeCheck { expected: String, got: String },
}
/// Trait for types that can report their full type name for error messages.
/// Used by `BamlValue` variants to provide descriptive "got" values.
pub trait FullTypeName {
fn full_type_name(&self) -> String;
}
impl BamlError {
/// Create an internal error for unexpected bugs
pub fn internal(msg: impl Into<String>) -> Self {
BamlError::Internal(msg.into())
}
/// Create a type check error for expected runtime type mismatches.
///
/// - `T`: The expected type (must implement `BamlTypeName`)View on GitHub (pinned to bd85ce9dee)
Solutions
- Compare the 'expected' and 'got' in the message and fix the value's type at the call site.
- Regenerate the BAML client after any .baml schema change so generated types match the runtime.
- Validate input JSON shapes (e.g. with serde typed structs) before handing them to the BAML runtime.
Example fix
// before
let args = baml_types::BamlMap::from([("user", BamlValue::String("alice".into()))]);
// .baml expects a class User
// after
let args = baml_types::BamlMap::from([("user", BamlValue::Class("User".into(), user_fields))]); Defensive patterns
Strategy: type-guard
Validate before calling
// validate input JSON shape before calling the runtime let user: User = serde_json::from_value(input_json)?; // fails early on wrong types
Type guard
matches!(err, BamlError::TypeCheck { .. })
// or narrow a value:
fn as_string(v: &BamlValue) -> Option<&str> { if let BamlValue::String(s) = v { Some(s) } else { None } } Try / catch
match call {
Err(BamlError::TypeCheck { expected, got }) => {
eprintln!("fix input: expected {expected}, got {got}");
}
r => r?,
} Prevention
- Regenerate clients after every .baml schema edit.
- Deserialize inputs into typed structs before passing to BAML.
- Check 'expected' vs 'got' in the message to fix the exact field.
When it happens
Trigger: Calling runtime APIs that downcast or match on BamlValue variants (string vs class vs list, etc.) with a value of the wrong type — e.g. passing a string where a class instance or list is expected by a generated function signature.
Common situations: Hand-constructed BamlValue inputs that don't match the .baml function's parameter types; schema drift after editing a .baml file without regenerating the Rust client; passing a JSON value with the wrong shape into the runtime.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- {message}
- BAML Generate failed - Project has errors.
- failed to create engine: {e:?}
- failed to create engine: {e:?}
- baml.json.serialize failed: {e:?}
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/7d94b5fa3e57d652.
Report an issue: GitHub.