BoundaryML/baml · error
Invalid number: {n}
Error message
Invalid number: {n} What it means
The GEPA optimizer converts JSON test-case values into BamlValue so it can propose improvements and merge prompt variants. serde_json numbers that fit neither i64 nor f64 (e.g. arbitrarily large u64 values beyond f64/i64 range, or NaN-like representations not expressible) fall through both as_i64() and as_f64() and hit this bail. It's an internal conversion guard for numeric JSON inputs that BAML cannot represent.
Source
Thrown at engine/baml-runtime/src/optimize/gepa_runtime.rs:398
serde_json::to_string_pretty(&version_info).context("Failed to serialize version info")?;
std::fs::write(version_file, version_json).context("Failed to write .gepa_version")?;
Ok(())
}
/// Convert serde_json::Value to BamlValue
fn json_to_baml_value(val: serde_json::Value) -> Result<BamlValue> {
match val {
serde_json::Value::Null => Ok(BamlValue::Null),
serde_json::Value::Bool(b) => Ok(BamlValue::Bool(b)),
serde_json::Value::Number(n) => {
if let Some(i) = n.as_i64() {
Ok(BamlValue::Int(i))
} else if let Some(f) = n.as_f64() {
Ok(BamlValue::Float(f))
} else {
anyhow::bail!("Invalid number: {n}")
}
}
serde_json::Value::String(s) => Ok(BamlValue::String(s)),
serde_json::Value::Array(arr) => {
let items: Result<Vec<_>> = arr.into_iter().map(json_to_baml_value).collect();
Ok(BamlValue::List(items?))
}
serde_json::Value::Object(obj) => {
let map: Result<indexmap::IndexMap<_, _>> = obj
.into_iter()
.map(|(k, v)| json_to_baml_value(v).map(|bv| (k, bv)))
.collect();
Ok(BamlValue::Map(map?))
}
}
}
/// Convert BamlValue to serde_json::ValueView on GitHub (pinned to bd85ce9dee)
Solutions
- Change the value in your test-case JSON to a string (e.g. "9007199254740993") and parse it in the function
- Reduce the number to fit in i64/f64 range in the dataset
- Quote large integers in the optimizer dataset files so they arrive as JSON strings
- If this is a bug in your BAML version, upgrade BAML — the converter may have gained big-number support
Example fix
// before (test case JSON)
{ "order_id": 9223372036854775807 }
// after
{ "order_id": "9223372036854775807" }
// and change the BAML param type to string Defensive patterns
Strategy: validation
Validate before calling
function safeNumber(n: unknown): string | number {
if (typeof n === 'number') {
if (!Number.isSafeInteger(n) && Number.isInteger(n)) return n.toString(); // treat big ints as strings
return n;
}
return n as string;
}
// sanitize dataset JSON before handing it to the optimizer Type guard
function isOptimizerSafeNumber(n: number): boolean {
return Number.isFinite(n) && (Number.isInteger(n) ? Math.abs(n) <= Number.MAX_SAFE_INTEGER : true);
} Try / catch
try {
await optimizer.proposeImprovements(dataset);
} catch (e) {
if (/Invalid number/i.test(e.message)) {
console.error('A JSON number in the dataset is out of i64/f64 range; quote large integers as strings');
}
throw e;
} Prevention
- Serialize large IDs/timestamps as strings in datasets and prompts
- Validate dataset JSON number ranges before optimizer runs
- Avoid hand-editing numeric fields in optimizer datasets without range checks
When it happens
Trigger: json_to_baml_value receives a serde_json::Value::Number that is neither as_i64() nor as_f64() — practically, a JSON number larger than i64/f64 can represent (e.g. a u64 > 2^53 or > i64::MAX) while running propose_improvements or merge_variants on test cases.
Common situations: Test-case parameters or labels containing huge integer IDs (snowflake/timestamp-millis as raw JSON numbers); hand-edited dataset files with oversized numbers; JSON produced by tooling that serializes big integers natively.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Cannot convert media types to JSON
- unknown feedback field(s) {}; only "title" and "description"
- feedback field "{key}" must be a string
- feedback payload must be a JSON object like {"title": "..."}
- type `{ty}` can't be passed through auto-CLI; deliver it via
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/5f89c26ff6b10579.
Report an issue: GitHub.