From b1ab21664c5193170e13bbd99bd0825f6a2ba773 Mon Sep 17 00:00:00 2001 From: Sarthak Bhardwaj <100398847+SarthakB11@users.noreply.github.com> Date: Wed, 6 May 2026 14:48:50 +0530 Subject: [PATCH] fix(openai): accept null tool_call arguments in streaming chunks (#9035) --- crates/goose/src/providers/formats/openai.rs | 26 +++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/crates/goose/src/providers/formats/openai.rs b/crates/goose/src/providers/formats/openai.rs index 7633b857..ec880c6a 100644 --- a/crates/goose/src/providers/formats/openai.rs +++ b/crates/goose/src/providers/formats/openai.rs @@ -32,10 +32,17 @@ type ToolCallData = HashMap< ), >; +fn deserialize_null_default_string<'de, D>(deserializer: D) -> Result +where + D: serde::Deserializer<'de>, +{ + Ok(Option::::deserialize(deserializer)?.unwrap_or_default()) +} + #[derive(Serialize, Deserialize, Debug, Default)] struct DeltaToolCallFunction { name: Option, - #[serde(default)] + #[serde(default, deserialize_with = "deserialize_null_default_string")] arguments: String, } @@ -2435,4 +2442,21 @@ data: [DONE]"#; ); Ok(()) } + + #[test] + fn test_delta_tool_call_function_accepts_null_arguments() { + let raw = r#"{"arguments":null}"#; + let parsed: DeltaToolCallFunction = + serde_json::from_str(raw).expect("null arguments must deserialize"); + assert_eq!(parsed.arguments, ""); + + let raw = r#"{}"#; + let parsed: DeltaToolCallFunction = + serde_json::from_str(raw).expect("missing arguments must deserialize"); + assert_eq!(parsed.arguments, ""); + + let raw = r#"{"arguments":"{\"k\":1}"}"#; + let parsed: DeltaToolCallFunction = serde_json::from_str(raw).unwrap(); + assert_eq!(parsed.arguments, "{\"k\":1}"); + } }