BoundaryML/baml · error

includes() argument must be a string at

Error message

includes() argument must be a string at {:?}

What it means

The single argument passed to includes() must itself be a string; if it evaluates to any other BAML type, evaluate_method_call bails. The containment check is implemented as Rust's str::contains, which requires a string needle.

Solutions

  1. Convert the argument to a string (string interpolation or explicit conversion) before passing it: `s.includes("{{ x }}")`.
  2. Fix the declaration of the needle variable so it is a string type.
  3. Guard with a type check when the needle may be null or another type.
  4. Check the error span to find the argument expression and fix its type.

Example fix

// before
let has = text.includes(errorCode);   // errorCode is an int
// after
let has = text.includes("{{ errorCode }}");
Defensive patterns

Strategy: type-guard

Validate before calling

if (typeof needle !== 'string') {
  throw new Error('includes() argument must be a string, got: ' + typeof needle);
}

Type guard

const isStr = (v) => typeof v === 'string';

Try / catch

try {
  const res = await b.Function(args);
} catch (e) {
  if (String(e.message).includes('includes() argument must be a string')) {
    // coerce the argument with string interpolation and retry
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling `s.includes(x)` where `x` is an int, bool, null, array, or map — e.g. searching for a numeric token without quoting it.

Common situations: Searching for a number without converting it to a string (e.g. includes(version) where version is an int); passing a null optional value as the needle; nested field from JSON input assumed to be a string.

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


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

Appendix: source

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

                bail!("trim() method takes no arguments at {:?}", meta.0);
            }
            Ok(BamlValueWithMeta::String(
                s.trim().to_string(),
                meta.clone(),
            ))
        }
        "includes" => {
            let BamlValueWithMeta::String(s, _) = receiver else {
                bail!(
                    "includes() method only available on strings at {:?}",
                    meta.0
                );
            };
            if args.len() != 1 {
                bail!("includes() method takes exactly 1 argument at {:?}", meta.0);
            }
            let BamlValueWithMeta::String(search, _) = &args[0] else {
                bail!("includes() argument must be a string at {:?}", meta.0);
            };
            Ok(BamlValueWithMeta::Bool(
                s.contains(search.as_str()),
                meta.clone(),
            ))
        }
        "startsWith" => {
            let BamlValueWithMeta::String(s, _) = receiver else {
                bail!(
                    "startsWith() method only available on strings at {:?}",
                    meta.0
                );
            };
            if args.len() != 1 {
                bail!(
                    "startsWith() method takes exactly 1 argument at {:?}",
                    meta.0
                );

View on GitHub (pinned to bd85ce9dee)