You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
While investigating a forced-function bug I found that SetFunctionCallString (mode field) is being called where SetFunctionCallNameString (specific-function name) is required. This silently breaks grammar-based forcing for tool_choice:{type:"function", function:{name:"X"}} — the model gets the tools, grammar is NOT forced, and output arrives as free-text rather than tool_calls.
core/http/middleware/request.go:322-335 unmarshals ToolsChoice into functions.Tool via json.Unmarshal. For the string case (e.g. tool_choice: "required"), json.Unmarshal([]byte("required"), &toolChoice) fails — the error is silently discarded via _ =, and input.FunctionCall is set to {"name": ""}. Downstream SetFunctionCallNameString("") runs with an empty string — the "required" mode is never applied.
Proposed follow-up
Either consolidate tool_choice parsing into one helper (e.g. in the middleware) and have all endpoints call it, or fix each site in a focused follow-up PR. Happy to take either on after #9509 lands.
While investigating a forced-function bug I found that
SetFunctionCallString(mode field) is being called whereSetFunctionCallNameString(specific-function name) is required. This silently breaks grammar-based forcing fortool_choice:{type:"function", function:{name:"X"}}— the model gets the tools, grammar is NOT forced, and output arrives as free-text rather thantool_calls.Affected call sites
core/http/middleware/request.go:620(MergeOpenResponsesConfig,/v1/responses) — fix proposed in fix(openresponses): parse OpenAI-spec nested tool_choice + use correct setter #9509core/http/endpoints/anthropic/messages.go:883(Anthropic messages endpoint)core/http/endpoints/openai/realtime_model.go:171core/http/endpoints/openresponses/responses.go:776All four follow the same pattern:
```go
if name, ok := tc["name"].(string); ok {
cfg.SetFunctionCallString(name) // ← writes mode field
}
```
The correct setter is
SetFunctionCallNameString(read byShouldCallSpecificFunctionandFunctionToCall).Additional issue: /v1/chat/completions string tool_choice
core/http/middleware/request.go:322-335unmarshalsToolsChoiceintofunctions.Toolviajson.Unmarshal. For the string case (e.g.tool_choice: "required"),json.Unmarshal([]byte("required"), &toolChoice)fails — the error is silently discarded via_ =, andinput.FunctionCallis set to{"name": ""}. DownstreamSetFunctionCallNameString("")runs with an empty string — the"required"mode is never applied.Proposed follow-up
Either consolidate tool_choice parsing into one helper (e.g. in the middleware) and have all endpoints call it, or fix each site in a focused follow-up PR. Happy to take either on after #9509 lands.