BoundaryML/baml · error

replace() method takes exactly 2 arguments at {:?}

Error message

replace() method takes exactly 2 arguments at {:?}

What it means

The "replace" string method requires exactly 2 arguments (search, replacement). The interpreter bails when args.len() != 2, reporting the source span. The arity check happens after the receiver type check, so the receiver was a valid string.

Source

Thrown at engine/baml-compiler/src/thir/interpret.rs:2977

            };
            let BamlValueWithMeta::Int(end, _) = &args[1] else {
                bail!("substring() end argument must be an int at {:?}", meta.0);
            };

            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,

View on GitHub (pinned to bd85ce9dee)

Solutions

  1. Supply exactly two arguments: search string and replacement string
  2. If only one argument was intended, pass an empty string "" as the replacement or use a different method
  3. If you wanted to replace a literal with nothing, write replace("x", "")

Example fix

// before
let out = s.replace("BAD");
// after
let out = s.replace("BAD", "");
Defensive patterns

Strategy: validation

Validate before calling

// replace requires exactly 2 string args: s.replace(search, replacement)

Try / catch

try { out = s.replace(a, b); } catch (e) { log("replace arity error: " + e); }

Prevention

When it happens

Trigger: Calling str.replace() with 0, 1, 3+ arguments, e.g. replace("a") (missing replacement) or replace("a","b","c") (extra argument).

Common situations: Porting code from languages where replace/replaceAll takes a regex-only single argument (e.g. JS str.replace(regex) with implicit empty replacement semantics), or hand-editing expressions and forgetting the second argument.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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