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

  1. Check the JSON payload at the failing path and correct/normalize the out-of-range number
  2. Cap or clamp the value in the producer before conversion
  3. If arbitrary precision is needed, type the field as string and parse manually downstream
  4. 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

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


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