BoundaryML/baml · error · anyhow::Error

Invalid numeric value: {}

Error message

Invalid numeric value: {}

What it means

When converting AST numeric literals into IR expressions, BAML first tries parsing as an integer and then as an f64 float. If the literal parses as neither, it raises 'Invalid numeric value'. This guards against malformed numbers reaching the IR.

Source

Thrown at engine/baml-lib/baml-core/src/ir/repr.rs:368

        match self {
            ast::Expression::BoolValue(val, span) => Ok(Expr::Atom(BamlValueWithMeta::Bool(
                *val,
                (span.clone(), Some(TypeIR::bool())),
            ))),
            ast::Expression::NumericValue(val, span) => {
                // Prefer int when it parses cleanly; otherwise fall back to float.
                if let Ok(v) = val.parse::<i64>() {
                    Ok(Expr::Atom(BamlValueWithMeta::Int(
                        v,
                        (span.clone(), Some(TypeIR::int())),
                    )))
                } else if let Ok(f) = val.parse::<f64>() {
                    Ok(Expr::Atom(BamlValueWithMeta::Float(
                        f,
                        (span.clone(), Some(TypeIR::float())),
                    )))
                } else {
                    Err(anyhow!("Invalid numeric value: {}", val))
                }
            }
            ast::Expression::StringValue(val, span) => Ok(Expr::Atom(BamlValueWithMeta::String(
                val.to_string(),
                (span.clone(), Some(TypeIR::string())),
            ))),
            ast::Expression::RawStringValue(val) => Ok(Expr::Atom(BamlValueWithMeta::String(
                val.value().to_string(),
                (val.span().clone(), Some(TypeIR::string())),
            ))),
            ast::Expression::JinjaExpressionValue(val, span) => Ok(Expr::Atom(
                BamlValueWithMeta::String(val.to_string(), (span.clone(), Some(TypeIR::string()))),
            )),
            ast::Expression::Array(vals, span) => {
                let new_items = vals
                    .iter()
                    .map(|v| v.repr(db))
                    .collect::<Result<Vec<_>>>()?;

View on GitHub (pinned to bd85ce9dee)

Solutions

  1. Locate the numeric literal named in the error and correct its syntax.
  2. Replace unsupported formats (underscores, suffixes, hex) with plain decimal notation.
  3. Split invalid multi-dot values or quote them as strings if they are identifiers-like.

Example fix

// before
retry_policy p {
  max_retries 1.2.3
}
// after
retry_policy p {
  max_retries 3
}
Defensive patterns

Strategy: validation

Validate before calling

# validate numeric literals in .baml before compiling
import re
for tok in re.findall(r'(?<![\w.])\d[\d.\w_]*', src):
    try:
        int(tok) if '.' not in tok and 'e' not in tok.lower() else float(tok)
    except ValueError:
        print(f"invalid numeric literal: {tok}")

Try / catch

match expr_repr(db) {
    Ok(e) => e,
    Err(e) if e.to_string().starts_with("Invalid numeric value") => {
        eprintln!("correct the malformed numeric literal in the .baml file");
        return Err(e);
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: repr(db) on an ast::Expression::NumberValue whose text cannot be parsed by Rust's i64 or f64 parsers — e.g. literals with invalid characters, multiple decimal points, or unsupported numeric syntax like hex/underscores where unsupported.

Common situations: Hand-edited numeric literals in .baml files with typos (e.g. '1.2.3', '12_000'); pasting numbers from other languages with unsupported suffixes or formats.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


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