BoundaryML/baml · error · BamlClientFinishReasonError

BamlError: BamlClientError: BamlClientFinishReasonError

Error message

BamlError: BamlClientError: BamlClientFinishReasonError: {message}

What it means

BamlClientFinishReasonError is thrown when the LLM response's finish reason indicates failure — typically the model stopped because it hit the max token limit instead of completing the output. The error JSON includes prompt, raw_output, finish_reason, and detailed_message.

Solutions

  1. Increase max_tokens in the client options
  2. Shorten the prompt or requested output size
  3. Check finish_reason in the error payload to confirm truncation
  4. Switch to a model with a larger context window

Example fix

// before
client GPT4 { provider openai options { model gpt-4 max_tokens 100 } }
// after
client GPT4 { provider openai options { model gpt-4 max_tokens 4096 } }
Defensive patterns

Strategy: try-catch

Validate before calling

// budget check before the call
const estimatedPromptTokens = Math.ceil(promptText.length / 4);
if (estimatedPromptTokens + expectedOutputTokens > maxTokens) console.warn('Token budget may truncate output');

Type guard

const isFinishReasonError = (e: unknown): boolean => String(e).includes('BamlClientFinishReasonError');

Try / catch

try {
  return await b.MyFunction(args);
} catch (e) {
  if (isFinishReasonError(e)) {
    // finish_reason is 'length' — retry with more max_tokens or shorter output
    return await b.MyFunction(args, { clientOverride: 'GPT4LargeBudget' });
  }
  throw e;
}

Prevention

When it happens

Trigger: finish_reason is 'length' (or another non-success reason) on every retry, so the driver gives up and calls throw_baml_client_finish_reason_error from from_anyhow_error.

Common situations: max_tokens set too low for the requested output, long prompts consuming the context budget, or the model truncating large structured outputs.

Related errors


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

Appendix: source

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

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

fn throw_baml_client_finish_reason_error(
    prompt: &str,
    raw_output: &str,
    message: &str,
    finish_reason: Option<&str>,
    detailed_message: Option<&str>,
) -> napi::Error {
    let error_json = serde_json::json!({
        "type": "BamlClientFinishReasonError",
        "prompt": prompt,
        "raw_output": raw_output,
        "message": format!("BamlError: BamlClientError: BamlClientFinishReasonError: {}", message),
        "finish_reason": finish_reason,
        "detailed_message": detailed_message,
    });
    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())

View on GitHub (pinned to bd85ce9dee)