Skip to content

Normalize blank tool-call content - #3

Open
Yiivgeny wants to merge 6 commits into
gonkalabs:mainfrom
Yiivgeny:blank-tool-call-content-fix
Open

Normalize blank tool-call content#3
Yiivgeny wants to merge 6 commits into
gonkalabs:mainfrom
Yiivgeny:blank-tool-call-content-fix

Conversation

@Yiivgeny

Copy link
Copy Markdown

Summary

Fix native tool-call request normalization for OpenAI-compatible clients that send assistant tool-call messages with blank content.

Current main contains a compatibility bug: when a client sends an assistant message with tool_calls and content as an empty or whitespace-only string, Gonka upstream can reject the request with:

{"error":{"message":"messages[1].content: must not be empty"}}

This request shape is produced by the latest version of opencode during tool/skill calls.

Problem

OpenAI-compatible tool-call turns may contain an assistant message like:

{
  "role": "assistant",
  "content": "",
  "tool_calls": [...]
}

or:

{
  "role": "assistant",
  "content": " ",
  "tool_calls": [...]
}

Gonka upstream accepts content: null for this case, but rejects blank string content, at least for Qwen.

Reproduction

Against a proxy running current main:

curl -sS -X POST http://127.0.0.1:8081/v1/chat/completions \
  -H 'Content-Type: application/json' \
  -d '{
    "model": "Qwen/Qwen3-235B-A22B-Instruct-2507-FP8",
    "stream": false,
    "max_tokens": 1,
    "messages": [
      {"role": "user", "content": "call test tool"},
      {
        "role": "assistant",
        "content": "",
        "tool_calls": [
          {
            "id": "call_1",
            "type": "function",
            "function": {
              "name": "test_tool",
              "arguments": "{}"
            }
          }
        ]
      },
      {
        "role": "tool",
        "tool_call_id": "call_1",
        "content": "ok"
      }
    ],
    "tools": [
      {
        "type": "function",
        "function": {
          "name": "test_tool",
          "description": "test",
          "parameters": {
            "type": "object",
            "properties": {}
          }
        }
      }
    ]
  }'

Expected: request is normalized and forwarded successfully.

Actual:

{"error":{"message":"messages[1].content: must not be empty"}}

The same issue is currently visible on the public proxy:

curl -sS -X POST https://proxy.gonka.gg/v1/chat/completions \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer <TOKEN>' \
  -d '{ ...same payload as above... }'

https://proxy.gonka.gg/v1 returns the same messages[1].content: must not be empty error for Qwen when content is "" or whitespace-only. The same request succeeds when content is changed to null.

Fix

In native tool-call mode, normalize assistant messages that have tool_calls and blank string content to:

"content": null

This preserves the OpenAI-compatible tool-call shape while avoiding Gonka upstream’s blank-content validation error.

Validation

  • Added unit coverage for blank assistant tool-call content normalization.
  • Verified locally with:
    • go test ./internal/api
    • go test ./...
  • Verified smoke tests through local LiteLLM -> opengnk path:
    • Qwen with content: "" now returns 200
    • Kimi with content: " " now returns 200

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants