BoundaryML/baml · error
baml.json.serialize failed: {e:?}
Error message
baml.json.serialize failed: {e:?} What it means
This error is produced by serialize_via_baml_json in the BAML executor when the `baml.json` external function fails while serializing a value (typically a class/object) to a JSON string. The call to the baml.json function is awaited and any failure from it is wrapped with anyhow! with the underlying error debug-formatted. It exists to carry the nested evaluation error into the output-writing pipeline (write_output_with_context) with a clear origin prefix.
Source
Thrown at baml_language/crates/baml_exec/src/output.rs:109
/// runtime-value dispatch honors user `baml.ToJson` overrides at every depth.
async fn serialize_via_baml_json(
engine: &Arc<BexEngine>,
value: BexExternalValue,
return_type: &RuntimeTy,
helper_context: &HelperCallContext,
) -> Result<String> {
let result = engine
.call_function(
"baml.json.serialize",
vec![value],
helper_context.call_context(indexmap::IndexMap::from([(
"T".to_string(),
return_type.clone(),
)])),
true,
)
.await
.map_err(|e| anyhow!("baml.json.serialize failed: {e:?}"))?;
match result {
BexExternalValue::String(s) => Ok(s.to_string()),
other => Err(anyhow!(
"baml.json.serialize returned non-string value: {other:?}"
)),
}
}
/// Human-readable formatting for `BexExternalValue`.
///
/// Thin wrapper over [`BexExternalValue::render_readable`] — the canonical
/// structural renderer, shared with the engine's uncaught-throw rendering so
/// `baml run` output and a leaked `throw` render identically.
pub fn format_value(value: &BexExternalValue) -> String {
value.render_readable()
}
View on GitHub (pinned to bd85ce9dee)
Solutions
- Read the wrapped `{e:?}` payload to identify the underlying baml.json evaluation failure and fix the value/type it complains about
- Verify the value being serialized matches the declared return_type (e.g. class field types) before calling the output writer
- Check that the LLM response is valid and the function's output schema compiles/evaluates correctly (run `baml test` / inspect intermediate result)
- Upgrade baml_language / the runtime engine if the failing serialization is a known bug
Example fix
// before return_type.clone(), // after // ensure declared return type matches the actual value schema // e.g. change fn return type or the value so baml.json receives a compatible class
Defensive patterns
Strategy: try-catch
Validate before calling
// before calling write_output_with_context, confirm the value matches the declared return type schema
if !matches_return_type(value, expected_return_type) {
return Err("value does not match declared return type; baml.json.serialize would fail");
} Type guard
fn is_serializable_string_result(v: &BexExternalValue) -> bool {
matches!(v, BexExternalValue::String(_))
} Try / catch
match serialize_via_baml_json(...).await {
Ok(json) => use(json),
Err(e) if e.to_string().contains("baml.json.serialize failed") => {
log::error!("serialization failed: {e:#}"); // inspect wrapped {e:?} cause
fallback_render(value)
}
Err(e) => return Err(e),
} Prevention
- Validate the runtime value against the declared return type before output serialization
- Keep the runtime engine and baml_language versions aligned
- Run `baml test` on functions whose output feeds baml.json serialization
- Log the wrapped cause ({e:#}) to pinpoint the underlying failure quickly
When it happens
Trigger: Calling write_output_with_context with a return type that routes through serialize_via_baml_json when the `baml.json` builtin/function evaluation fails — e.g. the runtime value cannot be converted by baml.json, the baml.json function itself errors, or the runtime/engine call rejects the arguments (type + `true` flag) passed in.
Common situations: Serializing a BAML class value whose fields contain types baml.json cannot handle; runtime engine errors during function invocation; mismatches between the return_type passed to baml.json and the actual value produced by the LLM function; partial or malformed results from an LLM response that fails conversion.
Understand the failure class
Background: json.Marshal / "failed to marshal" errors in Go: why "unsupported type" happens and how to fix it — this error's family across 22 libraries.
Related errors
- baml.json.serialize returned non-string value: {other:?}
- Failed to deserialize response: {0}
- failed to serialize BAML bytecode: {e}
- failed to create engine: {e:?}
- failed to create engine: {e:?}
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/87280b1df03b1122.
Report an issue: GitHub.