BoundaryML/baml · error · RuntimeError

Failed to parse LLM response: {}

Error message

Failed to parse LLM response: {}

What it means

The sibling branch of parsed_using_types: when the inner FunctionResult itself has no content (the LLM call failed), the FFI raises a Ruby RuntimeError 'Failed to parse LLM response: <result>'. Unlike the TypeError branch, this indicates no response existed to parse.

Source

Thrown at engine/language_client_ruby/ext/ruby_ffi/src/function_result.rs:54

        types: RModule,
        partial_types: RModule,
        allow_partials: bool,
    ) -> Result<Value> {
        let res = match rb_self.inner.result_with_constraints_content() {
            Ok(parsed) => ruby_to_json::RubyToJson::serialize_baml(
                ruby,
                types,
                partial_types,
                allow_partials,
                parsed.clone(),
            )
            .map_err(|e| {
                magnus::Error::new(
                    ruby.exception_type_error(),
                    format!("failing inside parsed_using_types: {e:?}"),
                )
            }),
            Err(_) => Err(Error::new(
                ruby.exception_runtime_error(),
                format!("Failed to parse LLM response: {}", rb_self.inner),
            )),
        };
        res
    }

    /// For usage in magnus::init
    ///
    /// TODO: use traits and macros to implement this
    pub fn define_in_ruby(module: &RModule) -> Result<()> {
        let cls = module.define_class("FunctionResult", class::object())?;

        cls.define_method(
            "parsed_using_types",
            method!(FunctionResult::parsed_using_types, 3),
        )?;

View on GitHub (pinned to bd85ce9dee)

Solutions

  1. Check the result succeeded before parsing (inspect content/status)
  2. Handle the RuntimeError and surface the underlying provider error
  3. Configure retries/fallbacks in the BAML function's client strategy
  4. Validate API keys and provider health

Example fix

// before
parsed = result.parsed_using_types(types, partial_types, false)
// after
parsed =
  begin
    result.parsed_using_types(types, partial_types, false)
  rescue RuntimeError => e
    warn "No LLM response to parse: #{e.message}"
    nil
  end
Defensive patterns

Strategy: try-catch

Validate before calling

# only parse when the call succeeded
next unless result && result.content # or equivalent success check

Try / catch

begin
  parsed = result.parsed_using_types(types, partial_types, false)
rescue RuntimeError => e
  logger.error("no LLM response: #{e.message}")
  parsed = nil
end

Prevention

When it happens

Trigger: Calling parsed_using_types on a FunctionResult whose content() is Err — failed/aborted LLM call, empty response — rather than a schema mismatch.

Common situations: Provider errors, rate limits, or timeouts that return a result object with no payload, then attempting typed parsing without checking success first.

Understand the failure class

Related errors


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