BoundaryML/baml · error

Parsing failed due to: {s:?}

Error message

Parsing failed due to: {s:?}

What it means

In parsed_value_to_response, the jsonish parser validates streaming/partial-parse state via validate_streaming_state; if that check reports a problem, the error string is wrapped with anyhow as 'Parsing failed due to: {s:?}'. It means the LLM output parsed as JSON-ish but its streaming state (partial vs complete values, allow_partials mode) is inconsistent with what the caller requested.

Source

Thrown at engine/baml-lib/jsonish/src/helpers/mod.rs:345

        baml_value.clone().into();
    let meta_field_type: BamlValueWithMeta<TypeIR> = baml_value.clone().into();

    let value_with_response_checks: BamlValueWithMeta<Vec<ResponseCheck>> = baml_value_with_meta
        .map_meta(|cs| {
            cs.iter()
                .map(|(label, expr, result)| {
                    let status = (if *result { "succeeded" } else { "failed" }).to_string();
                    ResponseCheck {
                        name: label.clone(),
                        expression: expr.0.clone(),
                        status,
                    }
                })
                .collect()
        });

    let baml_value_with_streaming = validate_streaming_state(ir, &baml_value, mode)
        .map_err(|s| anyhow::anyhow!("Parsing failed due to: {s:?}"))?;

    // Combine the baml_value, its types, the parser flags, and the streaming state
    // into a final value.
    // Node that we set the StreamState to `None` unless `allow_partials`.
    let response_value = baml_value_with_streaming
        .zip_meta(&value_with_response_checks)?
        .zip_meta(&meta_flags)?
        .zip_meta(&meta_field_type)?
        .map_meta(|(((x, y), z), ft)| {
            crate::ResponseValueMeta(z.clone(), y.clone(), x.clone(), ft.clone())
        });
    Ok(ResponseBamlValue(response_value))
}

#[cfg(test)]
mod tests {
    use super::*;

View on GitHub (pinned to bd85ce9dee)

Solutions

  1. Read the inner '{s:?}' detail in the message to identify the underlying validation failure
  2. If parsing partial stream chunks, enable allow_partials in the parse options
  3. Only call the final parse once the stream is complete (is_done=true)
  4. Log/inspect the raw LLM text; malformed streaming output may need a retry of the generation

Example fix

// before
let value = jsonish::from_str(&target_type, raw_chunk)?;
// after
let value = jsonish::from_str_with_flags(&target_type, raw_chunk, ParseOptions { allow_partials: true, ..Default::default() })?;
Defensive patterns

Strategy: try-catch

Validate before calling

fn can_parse(s: &str, allow_partials: bool) -> bool { !s.trim().is_empty() && (allow_partials || looks_complete(s)) }

Type guard

fn looks_complete(s: &str) -> bool { s.trim_end().ends_with('}') || s.trim_end().ends_with(']') }

Try / catch

match jsonish::from_str(&t, chunk) {
    Ok(v) => v,
    Err(e) if e.to_string().contains("Parsing failed due to") => fallback_partial(),
    Err(e) => return Err(e.into()),
}

Prevention

When it happens

Trigger: Calling BAML response parsing (from_str -> parsed_value_to_response) with a stream that is not done while allow_partials is not enabled, or with a partial value that cannot be validated as a valid streaming state for the requested mode.

Common situations: Consuming intermediate streaming chunks from an LLM without setting allow_partials, or feeding truncated tool-call/JSON output into the final (non-streaming) parse path.

Understand the failure class

Background: "Invalid JSON response" and "Failed to parse response" errors: when an API answers 200 but the body isn't the JSON your library expected — this error's family across 28 libraries.

Related errors


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