BoundaryML/baml · error · napi::Error

BamlError: BamlInvalidArgumentError: {msg}

Error message

BamlError: BamlInvalidArgumentError: {msg}

What it means

When from_anyhow_error sees LLMResponse::UserFailure(msg), BAML surfaces it as 'BamlError: BamlInvalidArgumentError: <msg>' with GenericFailure. UserFailure originates from user-supplied values failing checks (e.g. invalid media data, assertion failures on inputs) rather than the LLM provider.

Source

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

                    throw_baml_timeout_error(failed.client.as_str(), failed.message.as_str())
                }
                baml_runtime::internal::llm_client::ErrorCode::Other(_)
                | baml_runtime::internal::llm_client::ErrorCode::InvalidAuthentication
                | baml_runtime::internal::llm_client::ErrorCode::NotSupported
                | baml_runtime::internal::llm_client::ErrorCode::RateLimited
                | baml_runtime::internal::llm_client::ErrorCode::ServerError
                | baml_runtime::internal::llm_client::ErrorCode::ServiceUnavailable
                | baml_runtime::internal::llm_client::ErrorCode::UnsupportedResponse(_) => {
                    throw_baml_client_http_error(
                        failed.client.as_str(),
                        failed.message.as_str(),
                        &failed.code,
                        None,
                        failed.raw_response.as_deref(),
                    )
                }
            },
            LLMResponse::UserFailure(msg) => napi::Error::new(
                napi::Status::GenericFailure,
                format!("BamlError: BamlInvalidArgumentError: {msg}"),
            ),
            LLMResponse::InternalFailure(_) => napi::Error::new(
                napi::Status::GenericFailure,
                format!(
                    "BamlError: BamlClientError: Something went wrong with the LLM client: {err}"
                ),
            ),
            LLMResponse::Cancelled(msg) => napi::Error::new(
                napi::Status::GenericFailure,
                format!("BamlAbortError: Operation was aborted: {msg}"),
            ),
        }
    } else {
        napi::Error::new(napi::Status::GenericFailure, format!("BamlError: {err:?}"))
    }
}

View on GitHub (pinned to bd85ce9dee)

Solutions

  1. Read the {msg} suffix — it describes the rejected value.
  2. Validate media before calling: non-empty base64 that decodes, correct media type, reachable URL.
  3. Use Baml's constructors (BamlImage.fromBase64/fromUrl, etc.) instead of hand-built objects.

Example fix

// before
const img = await b.Describe(userInput); // userInput may be ''
// after
if (!userInput || userInput.trim() === '') throw new Error('image data required');
const img = await b.Describe(userInput);
Defensive patterns

Strategy: validation

Validate before calling

function assertNonEmptyBase64(s: string) {
  if (!s || s.length === 0) throw new Error('media base64 is empty');
  Buffer.from(s, 'base64'); // throws on invalid base64
}

Type guard

function isBamlUserFailure(e: unknown): e is Error {
  return e instanceof Error && /^BamlError: BamlInvalidArgumentError:/.test(e.message);
}

Try / catch

try {
  const res = await b.DescribeImage(imageInput);
} catch (e) {
  if (isBamlUserFailure(e)) {
    // message describes the rejected user input
    return { ok: false, reason: e.message.replace('BamlError: BamlInvalidArgumentError: ', '') };
  }
  throw e;
}

Prevention

When it happens

Trigger: Constructing BamlImage/BamlPdf/BamlAudio with malformed or empty base64/URL data, or otherwise passing user input the runtime validates and rejects, on any call_function/stream_function path.

Common situations: Uploading truncated base64 media; passing a URL the runtime cannot treat as media; empty strings for required media content; mixing up fromUrl/fromBase64 inputs.

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