Description
Serializing a FunctionCall with an allocated empty Args map omits the args field. Unmarshaling the result restores Args as nil instead of an empty map.
This affects consumers that persist and reload conversation history containing tool calls.
An explicitly supplied argument object changes representation across the serialization boundary, requiring downstream normalization. The behavior is reproducible usingencoding/json.
Environment details
- Programming language: Go
- OS: macOS
- Language runtime version: Go 1.27.1
- Package version:
google.golang.org/genai v1.71.0
Steps to reproduce
- Construct a
genai.FunctionCallwithArgs: map[string]any{}. - Marshal it to JSON, then unmarshal into a new
genai.FunctionCall. - Observe that the restored
Argsis nil.
package main
import (
"encoding/json"
"fmt"
"google.golang.org/genai"
)
func main() {
before := genai.FunctionCall{
Name: "list_tools",
Args: map[string]any{},
}
data, err := json.Marshal(before)
if err != nil {
panic(err)
}
var after genai.FunctionCall
if err := json.Unmarshal(data, &after); err != nil {
panic(err)
}
fmt.Printf("before Args is nil: %t\n", before.Args == nil)
fmt.Printf("JSON: %s\n", data)
fmt.Printf("after Args is nil: %t\n", after.Args == nil)
}Actual output:
before Args is nil: false
JSON: {"name":"list_tools"}
after Args is nil: true
Expected JSON:
{"args":{},"name":"list_tools"}The restored Args should remain a non-nil empty map. Originally nil arguments should continue to be omitted.
Possible fix
The field currently uses:
Args map[string]any `json:"args,omitempty"`Updating to json:"args,omitzero" (supported by required Go 1.24) would preserve explicit empty objects.
types.go is generated, so this change would need to be made in the generator that produces FunctionCall.Args. The tag change above describes the intended generated output.
I’m happy to provide a regression test or demonstration PR if useful.
Net Result
Fixing this at the SDK serialization boundary would avoid each downstream consumer needing its own workaround. Regression coverage could check nil, empty, and populated arguments, both directly and nested inside Content.
Related
Precedent: #198 fixed dropped explicit zero values during conversion, and #221 added JSON round-trip tests.
Activity
Sivasankaran25 commentedon Sep 17, 2026
Hi @alexdarbyshire,
Thank you for opening this issue! We have reproduced the issue on our end and will be filing a bug internally.
fix(adk): guard nil tool-call args and coerce to empty object in Open…
fix: keep an empty FunctionCall.Args map on JSON round trip
fix: keep an empty FunctionCall.Args map on JSON round trip
fix: keep an empty FunctionCall.Args map on JSON round trip
fix: keep an empty FunctionCall.Args map on JSON round trip