BoundaryML/baml · error
Expected float, got {}
Error message
Expected float, got {} What it means
Thrown during JSON-to-BAML conversion when a JSON number cannot be converted to f64 for a Float target type. as_f64() fails essentially only for values outside f64's representable range or non-finite handling, since JSON numbers map to f64 otherwise. It enforces the declared BAML type rather than coercing.
Source
Thrown at engine/baml-compiler/src/thir/interpret.rs:2627
use serde_json::Value as JsonValue;
match (json, target_type) {
(JsonValue::Null, _) => Ok(BamlValueWithMeta::Null(meta.clone())),
(JsonValue::Bool(b), TypeIR::Primitive(baml_types::TypeValue::Bool, _)) => {
Ok(BamlValueWithMeta::Bool(*b, meta.clone()))
}
(JsonValue::Number(n), TypeIR::Primitive(baml_types::TypeValue::Int, _)) => {
if let Some(i) = n.as_i64() {
Ok(BamlValueWithMeta::Int(i, meta.clone()))
} else {
bail!("Expected integer, got {}", n)
}
}
(JsonValue::Number(n), TypeIR::Primitive(baml_types::TypeValue::Float, _)) => {
if let Some(f) = n.as_f64() {
Ok(BamlValueWithMeta::Float(f, meta.clone()))
} else {
bail!("Expected float, got {}", n)
}
}
(JsonValue::String(s), TypeIR::Primitive(baml_types::TypeValue::String, _)) => {
Ok(BamlValueWithMeta::String(s.clone(), meta.clone()))
}
(JsonValue::Array(arr), TypeIR::List(elem_type, _)) => {
let mut baml_list = Vec::new();
for item in arr {
baml_list.push(json_to_baml(item, elem_type, meta)?);
}
Ok(BamlValueWithMeta::List(baml_list, meta.clone()))
}
(JsonValue::Object(obj), TypeIR::Map(_, value_type, _)) => {
let mut baml_map = BamlMap::new();
for (key, value) in obj {
baml_map.insert(key.clone(), json_to_baml(value, value_type, meta)?);
}
Ok(BamlValueWithMeta::Map(baml_map, meta.clone()))View on GitHub (pinned to bd85ce9dee)
Solutions
- Check the JSON payload at the failing path and correct/normalize the out-of-range number
- Cap or clamp the value in the producer before conversion
- If arbitrary precision is needed, type the field as string and parse manually downstream
- Validate numeric ranges of upstream JSON before calling the BAML converter
Example fix
// before (JSON)
{"ratio": 1e400}
// after (JSON)
{"ratio": 1.0} // or send "1e400" as a string field Defensive patterns
Strategy: validation
Validate before calling
function ensureFloat(n: unknown): number {
if (typeof n !== 'number' || !Number.isFinite(n)) {
throw new Error(`Expected finite float, got ${n}`);
}
return n;
} Try / catch
try {
value = parseJsonToBamlValue(json, schema);
} catch (e) {
if (String(e).startsWith('Expected float')) {
// clamp or normalize the out-of-range number
}
throw e;
} Prevention
- Clamp numbers to f64 range upstream
- Reject non-finite magnitudes before conversion
- Use string fields for extreme-precision values
When it happens
Trigger: parse_json_to_baml_value / json_to_baml receives (Number, TypeIR::Float) where n.as_f64() returns None — practically, extremely large magnitudes like 1e400 or malformed arbitrary-precision numbers the JSON crate cannot represent as f64.
Common situations: LLM or upstream API emitting absurdly large numeric literals (1e999) into a float field; copy-pasted JSON with scientific notation beyond double range.
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
- baml.json.deserialize failed: {e:?}
- Expected integer, got {}
- type `{ty}` can't be passed through auto-CLI; deliver it via
- --json-args must be a JSON object, got: {json}
- missing required argument `{name}` (type: {ty}). pass it via
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/b9e7849d843e0e8b.
Report an issue: GitHub.