BoundaryML/baml · error · napi::Error

BamlError: BamlInvalidArgumentError: {message}

Error message

BamlError: BamlInvalidArgumentError: {message}

What it means

invalid_argument_error builds a napi::Error with napi::Status::InvalidArg wrapping 'BamlError: BamlInvalidArgumentError: <message>'. Since custom JS error classes are not yet supported by napi-rs, BAML encodes its error taxonomy in the message string, surfaced to JS as a generic Error.

Source

Thrown at engine/language_client_typescript/src/errors.rs:10

use baml_runtime::{
    errors::ExposedError,
    internal::llm_client::{ErrorCode, LLMResponse},
    scope_diagnostics::ScopeStack,
};

// napi::Error::new(napi::Status::GenericFailure, e.to_string()))

pub fn invalid_argument_error(message: &str) -> napi::Error {
    napi::Error::new(
        napi::Status::InvalidArg,
        format!("BamlError: BamlInvalidArgumentError: {message}"),
    )
}

// Creating custom errors in JS is still not supported https://github.com/napi-rs/napi-rs/issues/1205
pub fn from_anyhow_error(err: anyhow::Error) -> napi::Error {
    if let Some(er) = err.downcast_ref::<ExposedError>() {
        match er {
            ExposedError::ValidationError {
                prompt,
                message,
                raw_output: raw_response,
                detailed_message,
                ..
            } => throw_baml_validation_error(
                prompt,
                raw_response,

View on GitHub (pinned to bd85ce9dee)

Solutions

  1. Read the {message} suffix — it names the invalid argument/expected type.
  2. Regenerate the client (`baml generate`) so TS signatures match the .baml files.
  3. Check argument types/values against the function signature (strings vs enums, media objects via BamlImage/BamlAudio/BamlPdf).

Example fix

// before
const res = await b.ExtractInfo(input.pdf);
// after
const res = await b.ExtractInfo(BamlPdf.fromBase64(input.pdfBase64, 'application/pdf'));
Defensive patterns

Strategy: try-catch

Type guard

function isBamlInvalidArgument(e: unknown): e is Error {
  return e instanceof Error && e.message.startsWith('BamlError: BamlInvalidArgumentError:');
}

Try / catch

try {
  const res = await b.MyFunction(input);
} catch (e) {
  if (isBamlInvalidArgument(e)) {
    // e.message after the prefix describes the bad argument
    throw new TypeError(e.message.replace('BamlError: BamlInvalidArgumentError: ', ''));
  }
  throw e;
}

Prevention

When it happens

Trigger: Any Rust-side validation failing an argument before/at runtime call: malformed client registry, bad function/argument names, invalid enum or media values passed into call_function, stream_function, build_request, or from_anyhow_error downcasting ScopeStack errors.

Common situations: Calling b.MyFunction with wrong argument types from JS/TS; referencing a function/client that doesn't exist in the .baml files; passing malformed Image/Audio/Pdf content; generated client out of sync with .baml definitions.

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/c88f9366eeec3abe. Report an issue: GitHub.