BoundaryML/baml · error · SyntaxError

error while parsing call_function args: {e}

Error message

error while parsing call_function args:
{e}

What it means

A Ruby SyntaxError raised by ClientRegistry.add_llm_client when its options hash cannot be converted to JSON via RubyToJson::convert_hash_to_json. The full conversion error (including per-key messages) is embedded after 'error while parsing call_function args:'.

Source

Thrown at engine/language_client_ruby/ext/ruby_ffi/src/types/client_registry.rs:31

    pub(crate) inner: RefCell<client_registry::ClientRegistry>,
}

impl ClientRegistry {
    pub fn new() -> Self {
        Self {
            inner: RefCell::new(client_registry::ClientRegistry::new()),
        }
    }

    pub fn add_llm_client(ruby: &Ruby, rb_self: &Self, args: &[Value]) -> Result<()> {
        let args = scan_args::<_, _, (), (), (), ()>(args)?;
        let (name, provider, options): (String, String, RHash) = args.required;
        let (retry_policy,): (Option<String>,) = args.optional;

        let options = match ruby_to_json::RubyToJson::convert_hash_to_json(options) {
            Ok(options) => options,
            Err(e) => {
                return Err(Error::new(
                    ruby.exception_syntax_error(),
                    format!("error while parsing call_function args:\n{e}"),
                ));
            }
        };

        let provider = match client_registry::ClientProvider::from_str(&provider) {
            Ok(provider) => provider,
            Err(e) => {
                return Err(Error::new(
                    ruby.exception_syntax_error(),
                    format!("Invalid provider: {e:?}"),
                ));
            }
        };

        let client_property =
            client_registry::ClientProperty::new(name, provider, retry_policy, options);

View on GitHub (pinned to bd85ce9dee)

Solutions

  1. Read the embedded {e} message for the exact key/path that failed conversion.
  2. Convert all option values to JSON primitives: strings for URIs/models, integers for numeric options.
  3. Use .to_s / explicit conversions on values taken from ENV or Rails config objects.
  4. Validate the hash with JSON.generate(options) in a test before calling add_llm_client.

Example fix

// before
registry.add_llm_client("claude", "anthropic", { base_url: URI("https://api.anthropic.com") })

// after
registry.add_llm_client("claude", "anthropic", { "base_url" => "https://api.anthropic.com" })
Defensive patterns

Strategy: validation

Validate before calling

def validated_options!(options)
  JSON.parse(options.to_json) # raises if any value is not JSON-safe
end
# call: registry.add_llm_client(name, provider, validated_options!(options))

Try / catch

begin
  registry.add_llm_client(name, provider, options)
rescue SyntaxError => e
  raise ArgumentError, "invalid client options: #{e.message}"
end

Prevention

When it happens

Trigger: Calling ClientRegistry#add_llm_client(name, provider, options, [retry_policy]) with an options RHash containing non-JSON-serializable values (Symbol objects, Ruby objects, wrong types).

Common situations: Dynamically registering clients in tests or apps with values sourced from Rails config/ENV wrappers; passing ActiveSupport::HashWithIndifferentAccess containing Symbol values; typo'd option value types (e.g. base_url: URI object instead of String).

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


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