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
- Increase max_tokens in the client options
- Shorten the prompt or requested output size
- Check finish_reason in the error payload to confirm truncation
- 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
- Set max_tokens generously relative to expected output size
- Keep prompts lean to preserve output budget
- Add a retry policy for finish-reason failures
- Monitor finish_reason values in production telemetry
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
- BamlAbortError: Operation was aborted
- BamlError: BamlClientError: BamlClientHttpError
- BamlError: BamlClientError: BamlTimeoutError
- BamlError: BamlClientError: Something went wrong with the…
- BamlValidationError
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)