BoundaryML/baml · error
replace() replacement argument must be a string at
Error message
replace() replacement argument must be a string at {:?} What it means
For the "replace" string method, the second argument (the replacement) must be a String value. The interpreter pattern-matches BamlValueWithMeta::String on args[1] and bails otherwise. Note the method replaces only the first occurrence (JavaScript-like behavior).
Solutions
- Convert the replacement to a string (ToString() or string interpolation)
- Ensure the second argument is a string literal or string-typed variable
- If replacing all occurrences is desired, be aware this method only replaces the first; chain calls or check for a replace-all variant
Example fix
// before
let out = s.replace("{{n}}", count);
// after
let out = s.replace("{{n}}", count.ToString()); Defensive patterns
Strategy: type-guard
Validate before calling
// arg1 must be a string: if (repl is string) { s.replace(search, repl); } Type guard
fn is_string(v: Value) -> bool { matches!(v, Value::String(_)) } Try / catch
try { out = s.replace(search, repl); } catch (e) { log(e); } Prevention
- Convert numeric replacements with ToString()
- Coalesce null fields to "" first
- Keep replacements as string literals where possible
When it happens
Trigger: Calling s.replace(search, nonString), e.g. replace("a", 3), replace("a", null), or passing a numeric LLM output as the replacement.
Common situations: Substituting in a numeric value (count, id, price) without converting it; a null field from a model response used as replacement text.
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
- replace() search argument must be a string at
- replace() method only available on strings at
- to_fixed() digits argument must be an int at
- baml.fetch_as: expected baml.fetch_as arg to be a string or…
- baml.json.serialize returned non-string value
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/dba10c42a76d1da4.
Report an issue: GitHub.
Appendix: source
Thrown at engine/baml-compiler/src/thir/interpret.rs:2983
let end = (*end as usize).min(s.len()).max(start);
Ok(BamlValueWithMeta::String(
s[start..end].to_string(),
meta.clone(),
))
}
"replace" => {
let BamlValueWithMeta::String(s, _) = receiver else {
bail!("replace() method only available on strings at {:?}", meta.0);
};
if args.len() != 2 {
bail!("replace() method takes exactly 2 arguments at {:?}", meta.0);
}
let BamlValueWithMeta::String(search, _) = &args[0] else {
bail!("replace() search argument must be a string at {:?}", meta.0);
};
let BamlValueWithMeta::String(replacement, _) = &args[1] else {
bail!(
"replace() replacement argument must be a string at {:?}",
meta.0
);
};
// Replace first occurrence only (matching JavaScript behavior)
let result = s.replacen(search.as_str(), replacement.as_str(), 1);
Ok(BamlValueWithMeta::String(result, meta.clone()))
}
"to_fixed" => {
let value = match receiver {
BamlValueWithMeta::Float(v, _) => *v,
BamlValueWithMeta::Int(v, _) => *v as f64,
_ => bail!(
"to_fixed() method only available on floats and ints at {:?}",
meta.0
),
};
View on GitHub (pinned to bd85ce9dee)