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
- Convert the argument to a string (string interpolation or explicit conversion) before passing it: `s.includes("{{ x }}")`.
- Fix the declaration of the needle variable so it is a string type.
- Guard with a type check when the needle may be null or another type.
- 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
- Quote numeric literals used as search needles.
- Convert numbers/bools to strings with interpolation before containment checks.
- Guard nullable fields before using them as search arguments.
- Type JSON-derived fields explicitly as strings when they feed string methods.
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
- startsWith() argument must be a string at
- includes() method only available on strings at
- includes() method takes exactly 1 argument at
- startsWith() method only available on strings at
- startsWith() method takes exactly 1 argument at
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)