{"record":{"id":"624186d6c0b64e2c","repo":"BoundaryML/baml","slug":"error-while-parsing-call-function-args-e-client-registry","errorCode":null,"errorMessage":"error while parsing call_function args:\n{e}","messagePattern":"error while parsing call_function args:\n(.+?)","errorType":"exception","errorClass":"SyntaxError","httpStatus":null,"severity":"error","filePath":"engine/language_client_ruby/ext/ruby_ffi/src/types/client_registry.rs","lineNumber":31,"sourceCode":"    pub(crate) inner: RefCell<client_registry::ClientRegistry>,\n}\n\nimpl ClientRegistry {\n    pub fn new() -> Self {\n        Self {\n            inner: RefCell::new(client_registry::ClientRegistry::new()),\n        }\n    }\n\n    pub fn add_llm_client(ruby: &Ruby, rb_self: &Self, args: &[Value]) -> Result<()> {\n        let args = scan_args::<_, _, (), (), (), ()>(args)?;\n        let (name, provider, options): (String, String, RHash) = args.required;\n        let (retry_policy,): (Option<String>,) = args.optional;\n\n        let options = match ruby_to_json::RubyToJson::convert_hash_to_json(options) {\n            Ok(options) => options,\n            Err(e) => {\n                return Err(Error::new(\n                    ruby.exception_syntax_error(),\n                    format!(\"error while parsing call_function args:\\n{e}\"),\n                ));\n            }\n        };\n\n        let provider = match client_registry::ClientProvider::from_str(&provider) {\n            Ok(provider) => provider,\n            Err(e) => {\n                return Err(Error::new(\n                    ruby.exception_syntax_error(),\n                    format!(\"Invalid provider: {e:?}\"),\n                ));\n            }\n        };\n\n        let client_property =\n            client_registry::ClientProperty::new(name, provider, retry_policy, options);","sourceCodeStart":13,"sourceCodeEnd":49,"githubUrl":"https://github.com/BoundaryML/baml/blob/bd85ce9dee1463ff04d27efd20531013a4ff46c1/engine/language_client_ruby/ext/ruby_ffi/src/types/client_registry.rs#L13-L49","documentation":"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:'.","triggerScenarios":"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).","commonSituations":"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).","solutions":["Read the embedded {e} message for the exact key/path that failed conversion.","Convert all option values to JSON primitives: strings for URIs/models, integers for numeric options.","Use .to_s / explicit conversions on values taken from ENV or Rails config objects.","Validate the hash with JSON.generate(options) in a test before calling add_llm_client."],"exampleFix":"// before\nregistry.add_llm_client(\"claude\", \"anthropic\", { base_url: URI(\"https://api.anthropic.com\") })\n\n// after\nregistry.add_llm_client(\"claude\", \"anthropic\", { \"base_url\" => \"https://api.anthropic.com\" })","handlingStrategy":"validation","validationCode":"def validated_options!(options)\n  JSON.parse(options.to_json) # raises if any value is not JSON-safe\nend\n# call: registry.add_llm_client(name, provider, validated_options!(options))","typeGuard":null,"tryCatchPattern":"begin\n  registry.add_llm_client(name, provider, options)\nrescue SyntaxError => e\n  raise ArgumentError, \"invalid client options: #{e.message}\"\nend","preventionTips":["Build option hashes with literal primitives, not Ruby objects (URI, Duration, Symbol).","Validate with JSON.generate before calling add_llm_client.","Centralize client registration in one helper that sanitizes options.","Check the embedded path:message detail to fix the exact key."],"tags":["ruby","client-registry","json","arguments"],"backgroundTag":"invalid-argument-format","analyzedSha":"bd85ce9dee1463ff04d27efd20531013a4ff46c1","analyzedAt":"2026-09-12T03:38:25.718Z","contentChangedAt":"2026-09-12T03:38:25.718Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}