BoundaryML/baml · error · SyntaxError

error while parsing call_function args: {e}

Error message

error while parsing call_function args:
{e}

What it means

Raised inside BAML's call_function when the Ruby keyword arguments hash cannot be converted to JSON for the function's parameters. RubyToJson::convert_hash_to_json fails on non-serializable values, and it raises a Ruby SyntaxError (not RuntimeError).

Source

Thrown at engine/language_client_ruby/ext/ruby_ffi/src/lib.rs:124

                .create_ctx_manager(BamlValue::String("ruby".to_string()), None),
        }
    }

    pub fn call_function(
        ruby: &Ruby,
        rb_self: &BamlRuntimeFfi,
        function_name: String,
        args: RHash,
        ctx: &RuntimeContextManager,
        type_registry: Option<&types::type_builder::TypeBuilder>,
        client_registry: Option<&types::client_registry::ClientRegistry>,
        collector: RArray,
        env_vars: HashMap<String, String>,
    ) -> Result<FunctionResult> {
        let args = match ruby_to_json::RubyToJson::convert_hash_to_json(args) {
            Ok(args) => args.into_iter().collect(),
            Err(e) => {
                return Err(Error::new(
                    ruby.exception_syntax_error(),
                    format!("error while parsing call_function args:\n{e}"),
                ));
            }
        };

        let mut collectors = Vec::new();
        for i in collector.into_iter() {
            collectors.push(<&Collector>::try_convert(i)?.inner.clone());
        }

        let retval = match rb_self.t.block_on(rb_self.inner.call_function(
            function_name.clone(),
            &args,
            &ctx.inner,
            type_registry.map(|t| &t.inner),
            client_registry.map(|c| c.inner.borrow_mut()).as_deref(),
            Some(collectors),

View on GitHub (pinned to bd85ce9dee)

Solutions

  1. Read the {e} detail to see which argument failed conversion.
  2. Convert unsupported values to JSON-native types (String, Integer, Float, Hash, Array, nil, true/false) before calling.
  3. Pass plain Hashes with string keys for nested structures.
  4. Add explicit serialization (e.g. .to_s / .iso8601 / .to_h) for domain objects.

Example fix

// before
Baml.call_function('ExtractResume', { start_date: Date.today }, ctx, ENV)
// after
Baml.call_function('ExtractResume', { 'start_date' => Date.today.iso8601 }, ctx, ENV)
Defensive patterns

Strategy: validation

Validate before calling

JSON_GENERABLE = [NilClass, TrueClass, FalseClass, Integer, Float, String, Array, Hash]
def ensure_jsonable(h)
  h.each do |k, v|
    raise TypeError, "#{k} is not JSON-serializable" unless JSON_GENERABLE.any? { |c| v.is_a?(c) }
    ensure_jsonable(v) if v.is_a?(Hash)
  end
end

Type guard

def jsonable?(v)
  [NilClass, TrueClass, FalseClass, Integer, Float, String].any? { |c| v.is_a?(c) } ||
    (v.is_a?(Array) && v.all? { |x| jsonable?(x) }) ||
    (v.is_a?(Hash) && v.values.all? { |x| jsonable?(x) })
end

Try / catch

begin
  res = Baml.call_function(fn, args, ctx, ENV.to_h)
rescue SyntaxError => e
  if e.message.include?('error while parsing call_function args')
    logger.error("Bad args for #{fn}: #{e.message}")
  end
  raise
end

Prevention

When it happens

Trigger: Baml.call_function(name, args, ctx, env_vars, collectors) where args contains values that cannot become JSON: unsupported objects, Ruby symbols, custom classes without JSON representation, deeply nested unsupported types.

Common situations: Passing Date/Time objects instead of ISO strings; passing Ruby symbols; passing File/IO objects; passing structs or OpenStructs the converter doesn't handle; typos leading to nested unsupported values.

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/e77aacb9bc520bd4. Report an issue: GitHub.