BoundaryML/baml · error · LlmOpError
SAP error
Error message
SAP error: {0} What it means
LlmOpError::SapError wraps a bex_sap::deserializer::coercer::ParsingError from the SAP deserializer coercer — the stage that coerces a parsed JSON-ish value into the target schema type. It indicates the value exists but cannot be coerced to the required shape.
Solutions
- Read the wrapped ParsingError to find the failing field/coercion
- Align the prompt's output schema with the expected BAML class exactly
- Make the schema fields optional where the model legitimately may omit them
- Retry the generation if the omission looks stochastic
Example fix
// before
class Result { score int }
// after
class Result { score int? } Defensive patterns
Strategy: try-catch
Validate before calling
fn has_required_fields(v: &serde_json::Value, required: &[&str]) -> bool {
required.iter().all(|k| v.get(k).is_some())
} Try / catch
match result {
Err(LlmOpError::SapError(pe)) => { eprintln!("coercion failed at {:?}", pe); adjust_prompt_and_retry() }
other => other,
} Prevention
- Keep the prompt's documented schema exactly in sync with the BAML class
- Mark fields optional when the model may omit them
- Sample a few generations in tests to catch flaky field omissions
When it happens
Trigger: The coercer fails while deserializing a jsonish value into the expected output class (missing required field, uncoercible value, wrong field types); the error is wrapped as SapError and later converted to a VmRustFnError/VmBamlError.
Common situations: Model omits a required field or invents extra ones; values are close-but-wrong types the coercer won't cast; schema changed after the prompt was written.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- {0}
- AbortError
- baml.json.deserialize failed
- BamlAbortError: Operation was aborted
- BamlError: BamlClientError: BamlClientFinishReasonError
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/d15d8c1821b60649.
Report an issue: GitHub.
Appendix: source
Thrown at baml_language/crates/sys_ops/src/sap.rs:64
/// Errors that can occur during LLM operations. Relocated verbatim from
/// `sys_llm`; only `ParseResponseError`, `JsonishError` and `SapError` are
/// still constructible now that the SAP parse entry points are the sole users.
#[derive(Debug, thiserror::Error)]
pub enum LlmOpError {
#[error("Expected {expected}, got {actual}")]
TypeError {
expected: &'static str,
actual: String,
},
#[error("Parse response error: {0}")]
ParseResponseError(String),
#[error("Jsonish error: {0}")]
JsonishError(::bex_sap::jsonish::JsonishError),
#[error("SAP error: {0}")]
SapError(::bex_sap::deserializer::coercer::ParsingError),
}
impl From<LlmOpError> for ::sys_types::VmRustFnError {
fn from(e: LlmOpError) -> Self {
let baml: ::sys_types::VmBamlError = match e {
LlmOpError::TypeError { expected, actual } => {
::sys_types::VmBamlError::InvalidArgument {
message: format!("expected {expected}, got {actual}"),
}
}
LlmOpError::ParseResponseError(e) => ::sys_types::VmBamlError::LlmClient { message: e },
LlmOpError::JsonishError(e) => ::sys_types::VmBamlError::LlmClient {
message: e.to_string(),
},
LlmOpError::SapError(e) => ::sys_types::VmBamlError::LlmClient {
message: e.to_string(),
},View on GitHub (pinned to bd85ce9dee)