BoundaryML/baml · error · TypeError
failed coercing BAML value to Ruby value: {e:?}
Error message
failed coercing BAML value to Ruby value: {e:?} What it means
This magnus::Error (Ruby TypeError) is raised by the BAML Ruby FFI's parse_llm_response after the LLM response has been parsed into a BAML value but the conversion of that BAML value back into a native Ruby value (via RubyToJson::serialize_baml) failed. It wraps the underlying serde/magnus conversion error, so the detailed cause is inside the {e:?} debug payload. It indicates the BAML runtime produced a value that could not be coerced into the Ruby object model.
Source
Thrown at engine/language_client_ruby/ext/ruby_ffi/src/lib.rs:296
type_registry.map(|t| &t.inner),
client_registry.map(|c| c.inner.borrow_mut()).as_deref(),
env_vars,
)
.map_err(|e| {
Error::new(
ruby.exception_runtime_error(),
format!(
"{:?}",
e.context(format!(
"error while parsing LLM response for function {function_name}"
))
),
)
})?;
ruby_to_json::RubyToJson::serialize_baml(ruby, types, partial_types, allow_partials, parsed)
.map_err(|e| {
magnus::Error::new(
ruby.exception_type_error(),
format!("failed coercing BAML value to Ruby value: {e:?}"),
)
})
}
}
fn invoke_runtime_cli(ruby: &Ruby, argv0: String, argv: Vec<String>) -> Result<u32> {
match baml_cli::run_cli(
std::iter::once(argv0).chain(argv).collect(),
baml_runtime::RuntimeCliDefaults {
output_type: baml_types::GeneratorOutputType::RubySorbet,
},
) {
Ok(exit_code) => Ok(exit_code.into()),
Err(e) => Err(Error::new(
ruby.exception_runtime_error(),
format!(View on GitHub (pinned to bd85ce9dee)
Solutions
- Inspect the wrapped {e:?} detail in the message to find the exact BAML value that failed coercion.
- Regenerate the BAML client (bundle baml-cli generate / baml-cli generate) so Ruby types match the current .baml schemas.
- Simplify the BAML function return type (avoid exotic nested/unions unsupported by the Ruby bridge) and re-test.
- Update the baml gem / ruby_ffi extension to the latest version, as coercion coverage improves between releases.
- Capture the full LLM response with a BAML collector and check whether the model returned malformed output that parsed into an unexpected value.
Example fix
// before (retrying blindly on every call)
begin
result = b.MyFunc(input)
rescue StandardError => e
retry
end
// after (log detail, regenerate client, narrow the return type)
begin
result = b.MyFunc(input)
rescue TypeError => e
Baml.logger.error("baml coercion failed: #{e.message}")
# run: bundle exec baml-cli generate, then retry once
end Defensive patterns
Strategy: try-catch
Validate before calling
return unless defined?(Baml::Ffi)
raise unless Gem::Specification.find_by_name('baml')&.version
# ensure client is regenerated:
raise 'run baml-cli generate' unless File.exist?(File.join(BAML_SRC_DIR, 'baml_client')) Type guard
def baml_result_ok?(result) result.is_a?(String) || result.is_a?(Hash) || result.respond_to?(:to_h) rescue StandardError false end
Try / catch
begin
result = b.MyFunc(input)
rescue TypeError => e
logger.error("BAML coercion failed: #{e.message}")
raise BamlCoercionError, e.message
end Prevention
- Regenerate the baml_client after every .baml schema change.
- Pin and keep the baml gem version in sync across environments.
- Prefer simple JSON-safe return types in BAML functions.
- Log the raw LLM output with a collector to diagnose unexpected parses.
When it happens
Trigger: Calling a BAML-generated function from Ruby (parse_llm_response) where the parsed response contains a BAML value type that RubyToJson::serialize_baml cannot represent, e.g. unexpected partial/streaming state, a mismatch between the declared return type and the actual parsed value, or a serde-level serialization failure inside serialize_baml.
Common situations: Streaming/partial responses whose completion state carries types the Ruby bridge does not support; schema drift after editing .baml return types without regenerating the client; deeply nested or unusual return types (unions, maps with non-string keys) hitting an unimplemented coercion path in the FFI.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- failed to convert Ruby object to JSON, errors were: {} Ruby
- {e:?}
- {e:?}
- {e}
- failed to serialize BAML bytecode: {e}
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/8529b13f4315c98d.
Report an issue: GitHub.