BoundaryML/baml · error
replace() search argument must be a string at
Error message
replace() search argument must be a string at {:?} What it means
For the "replace" string method, the first argument (the search substring) must be a String value. The interpreter pattern-matches BamlValueWithMeta::String on args[0] and bails otherwise. Plain substring search only — no regex or non-string needles.
Solutions
- Wrap the search argument in a string (e.g. ToString(), or quote the literal)
- Ensure the argument expression is statically typed/annotated as string
- Convert numeric search terms to their string form before the call
Example fix
// before let out = s.replace(id, "REDACTED"); // after let out = s.replace(id.ToString(), "REDACTED");
Defensive patterns
Strategy: type-guard
Validate before calling
// arg0 must be a string: if (search 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
- Quote search literals
- Convert numeric search terms with ToString()
- Validate LLM-sourced fields are strings before use
When it happens
Trigger: Calling s.replace(nonString, replacement), e.g. replace(42, "x"), replace(someMap, "x"), or passing a null from an LLM field as the search term.
Common situations: Passing numbers (like IDs) directly as the search argument; a variable inferred as int/float being used where a string literal was expected.
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() replacement 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/3ea36a27b9644e5c.
Report an issue: GitHub.
Appendix: source
Thrown at engine/baml-compiler/src/thir/interpret.rs:2980
};
let start = (*start as usize).min(s.len());
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.0View on GitHub (pinned to bd85ce9dee)