BoundaryML/baml · error · BamlClientHttpError

BamlError: BamlClientError: BamlClientHttpError: {message}

Error message

BamlError: BamlClientError: BamlClientHttpError: {message}

What it means

N-API error factory in the TypeScript client: wraps a runtime-side HTTP client failure into a structured BamlClientHttpError, embedding the status code, optional detailed message, and raw response into a JSON payload thrown to JS. The stringified message follows the BamlError: BamlClientError: BamlClientHttpError: chain used by the TS error-classification logic; from_anyhow_error routes qualifying anyhow errors here.

Source

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

    napi::Error::new(napi::Status::GenericFailure, error_json.to_string())
}

fn throw_baml_client_http_error(
    client_name: &str,
    message: &str,
    status_code: &ErrorCode,
    detailed_message: Option<&str>,
    raw_response: Option<&str>,
) -> napi::Error {
    let error_json = serde_json::json!({
        "type": "BamlClientHttpError",
        "client_name": client_name,
        "message": format!("BamlError: BamlClientError: BamlClientHttpError: {}", message),
        "status_code": status_code.to_u16(),
        "detailed_message": detailed_message,
        "raw_response": raw_response,
    });
    napi::Error::new(napi::Status::GenericFailure, error_json.to_string())
}

fn throw_baml_abort_error(detailed_message: Option<&str>) -> napi::Error {
    let error_json = serde_json::json!({
        "type": "BamlAbortError",
        "detailed_message": detailed_message,
    });
    napi::Error::new(napi::Status::GenericFailure, error_json.to_string())
}

fn throw_baml_timeout_error(client_name: &str, message: &str) -> napi::Error {
    let error_json = serde_json::json!({
        "type": "BamlTimeoutError",
        "client_name": client_name,
        "message": format!("BamlError: BamlClientError: BamlTimeoutError: {}", message),
    });
    napi::Error::new(napi::Status::GenericFailure, error_json.to_string())
}

View on GitHub (pinned to bd85ce9dee)

Solutions

  1. Read status_code and raw_response in the error payload to identify the cause
  2. 401/403: fix the API key / credentials in client options
  3. 429: add or strengthen a retry_policy with backoff, or reduce request rate
  4. Check provider status page and correct model/base_url in baml_src config

Example fix

// before
client GPT4 { provider openai options { api_key env.OPENAI_KEY_WRONG } }
// after
client GPT4 {
  provider openai
  options { api_key env.OPENAI_API_KEY }
  retry_policy Exponential
}
Defensive patterns

Strategy: retry

Validate before calling

if (!process.env[clientApiKeyEnvVar]) throw new Error(`Missing API key env var ${clientApiKeyEnvVar} for BAML client`);

Type guard

const isBamlHttpError = (e: unknown): boolean => String(e).includes('BamlClientHttpError');

Try / catch

try {
  return await b.MyFunction(args);
} catch (e) {
  if (isBamlHttpError(e)) {
    const detail = JSON.parse(String(e).replace(/^[^{]*/, ''));
    if (detail.status_code === 429) await sleep(2000);
    return await b.MyFunction(args); // safe retry for 429/5xx
  }
  throw e;
}

Prevention

When it happens

Trigger: Provider responds with 4xx/5xx during a BAML call and no retry policy recovers it — e.g. 401 invalid API key, 404 bad model name, 429 rate limit, 500 provider outage.

Common situations: Expired or missing API keys, wrong base_url, model names that don't exist for the account, quota exhaustion, provider downtime.

Understand the failure class

Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.

Related errors


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