BoundaryML/baml · error · RuntimeError

{e}

Error message

{e}

What it means

TypeBuilder#add_baml adds BAML source (and the runtime) to a type builder. Any error returned by the Rust add_baml implementation (parse errors, duplicate types, invalid references) is converted into a Ruby RuntimeError carrying e.to_string().

Source

Thrown at engine/language_client_ruby/ext/ruby_ffi/src/types/type_builder.rs:130

        Ok(baml_types::TypeIR::union(
            types
                .into_iter()
                .map(|t| t.inner.lock().unwrap().clone())
                .collect(),
        )
        .into())
    }

    pub fn add_baml(
        ruby: &magnus::Ruby,
        rb_self: &TypeBuilder,
        baml: String,
        runtime: &crate::BamlRuntimeFfi,
    ) -> Result<()> {
        rb_self
            .inner
            .add_baml(&baml, &runtime.inner)
            .map_err(|e| magnus::Error::new(ruby.exception_runtime_error(), e.to_string()))
    }

    // this implements ruby's friendly to_s method for converting objects to strings
    // when someone calls .to_s on a typebuilder in ruby, this method gets called
    // under the hood, it uses rust's display trait to format everything nicely
    // by using the same display logic across languages, we keep things consistent
    // this helps make debugging and logging work the same way everywhere :D
    pub fn to_s(&self) -> String {
        self.inner.to_string()
    }

    pub fn define_in_ruby(module: &RModule) -> Result<()> {
        let cls = module.define_class("TypeBuilder", class::object())?;

        cls.define_singleton_method("new", function!(TypeBuilder::new, 0))?;
        cls.define_method("to_s", method!(TypeBuilder::to_s, 0))?;
        cls.define_method("enum", method!(TypeBuilder::r#enum, 1))?;
        // TODO: Not exposed, Ruby doesn't work right now.

View on GitHub (pinned to bd85ce9dee)

Solutions

  1. Fix the BAML syntax/naming error reported in the message.
  2. Ensure add_baml is called only once per unique type and that dependencies are added before dependents.
  3. Pass the same BamlRuntimeFfi instance the client was built with.

Example fix

// before
tb.add_baml(broken_baml, runtime) # RuntimeError: parse error...
// after
begin
  tb.add_baml(valid_baml, runtime)
rescue RuntimeError => e
  raise "Invalid BAML source: #{e.message}"
end
Defensive patterns

Strategy: validation

Validate before calling

# validate BAML source parses before add_baml, e.g. run `baml-cli validate` or keep source in .baml files tested in CI

Try / catch

begin
  tb.add_baml(src, runtime)
rescue RuntimeError => e
  raise "add_baml failed: #{e.message}"
end

Prevention

When it happens

Trigger: Calling type_builder.add_baml(baml_string, runtime) with BAML source that fails to parse/merge, or with a runtime not compatible with the builder.

Common situations: Typo or syntax error in the BAML snippet, re-adding a file that defines an existing type/class/enum name, referencing types not yet defined, or mismatched runtime instance.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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