BoundaryML/baml · error
startsWith() argument must be a string at
Error message
startsWith() argument must be a string at {:?} What it means
The argument to startsWith() must be a string; a non-string prefix (int, bool, null, etc.) makes evaluate_method_call bail. The check is implemented with Rust's str::starts_with, which requires a string prefix.
Solutions
- Convert the argument to a string before passing it: `s.startsWith("{{ prefix }}")`.
- Fix the prefix variable's declaration so it is a string type.
- Guard with a type/null check when the prefix may not be a string.
- Use the error span to locate the argument expression and correct it.
Example fix
// before
let isBeta = build.startsWith(majorVersion); // int
// after
let isBeta = build.startsWith("{{ majorVersion }}"); Defensive patterns
Strategy: type-guard
Validate before calling
if (typeof prefix !== 'string') {
throw new Error('startsWith() argument must be a string, got: ' + typeof prefix);
} Type guard
const isStr = (v) => typeof v === 'string';
Try / catch
try {
const res = await b.Function(args);
} catch (e) {
if (String(e.message).includes('startsWith() argument must be a string')) {
// coerce the prefix with string interpolation and retry
}
throw e;
} Prevention
- Quote numeric prefixes (e.g. "2" not 2) in startsWith() calls.
- Interpolate non-string values into strings before prefix comparisons.
- Guard nullable prefix fields before use.
- Declare prefix sources as string-typed fields in the schema.
When it happens
Trigger: Calling `s.startsWith(x)` where `x` evaluates to a non-string — e.g. startsWith(version) with an int version number, or a null optional as the prefix.
Common situations: Checking a numeric prefix without quoting it; passing a field from JSON/map input assumed to be a string but typed as a number or bool; a null optional flowing in without a guard.
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
- includes() 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/fb68bbb01fdd5356.
Report an issue: GitHub.
Appendix: source
Thrown at engine/baml-compiler/src/thir/interpret.rs:2903
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
);
}
let BamlValueWithMeta::String(prefix, _) = &args[0] else {
bail!("startsWith() argument must be a string at {:?}", meta.0);
};
Ok(BamlValueWithMeta::Bool(
s.starts_with(prefix.as_str()),
meta.clone(),
))
}
"endsWith" => {
let BamlValueWithMeta::String(s, _) = receiver else {
bail!(
"endsWith() method only available on strings at {:?}",
meta.0
);
};
if args.len() != 1 {
bail!("endsWith() method takes exactly 1 argument at {:?}", meta.0);
}
let BamlValueWithMeta::String(suffix, _) = &args[0] else {
bail!("endsWith() argument must be a string at {:?}", meta.0);View on GitHub (pinned to bd85ce9dee)