BoundaryML/baml · error

startsWith() method only available on strings at

Error message

startsWith() method only available on strings at {:?}

What it means

THIR interpreter runtime error: the `startsWith()` method was invoked on a receiver that is not a String (e.g. a list, int, or null). The receiver type guard fails before the method body runs, aborting evaluation at the call site.

Solutions

  1. Coerce the receiver to a string before the call (interpolation or explicit conversion).
  2. Fix the upstream declaration so the receiver is a string.
  3. Branch on the receiver's type before calling startsWith().
  4. Use the reported span to locate and correct the receiver expression.

Example fix

// before
let isV2 = apiVersion.startsWith("2");  // apiVersion is a number
// after
let isV2 = "{{ apiVersion }}".startsWith("2");
Defensive patterns

Strategy: type-guard

Validate before calling

if (typeof value !== 'string') {
  throw new Error('startsWith() receiver must be a string, got: ' + typeof value);
}

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() method only available on strings')) {
    // stringify the receiver or fix its declared type and retry
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling `x.startsWith(prefix)` where `x` is a non-string value — int, float, bool, null, map, array — at runtime.

Common situations: Assuming an identifier or version field is a string when it parses as a number; calling startsWith on the result of a function whose return type changed; applying it to a null optional without checking.

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


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

Appendix: source

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

                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
                );
            }
            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(),
            ))
        }

View on GitHub (pinned to bd85ce9dee)