Billionmail/BillionMail · error

failed to unmarshal tool call arguments: %v, %s

Error message

failed to unmarshal tool call arguments: %v, %s

What it means

During streamed chat completion, tool-call argument chunks are accumulated and, for the http_request tool, JSON-unmarshalled into WebSearchParams. If the model produced malformed/incomplete JSON arguments, json.Unmarshal fails and the error (plus the raw arguments) is wrapped and returned, aborting the stream.

Source

Thrown at core/internal/service/askai/openai.go:687

					o.ThinkEnd = false
					o.IsThinkContent = false // Reset thinking content state after processing
					if o.IsThinking {
						o.IsThinking = false // Reset thinking state after processing
					}
				}
			}

			o.WriteEvent(request, messageBody, isText, false) // Write event to the response
		}
	}

	if len(toolCallMap) > 0 {
		// If there are tool calls, write them to the response
		for _, toolCall := range toolCallMap {
			if toolCall.Function.Name == TOOL_NAME_HTTP_REQUEST {
				var params WebSearchParams
				if err := json.Unmarshal([]byte(toolCall.Function.Arguments), &params); err != nil {
					return fmt.Errorf("failed to unmarshal tool call arguments: %v, %s", err, toolCall.Function.Arguments)
				}

				o.WriteEvent(request, "\n\n<tool>Requesting URL: "+params.Url, isText, false)
				// Call the HTTP request tool with the URL from the tool call
				responseContent := o.HttpRequestTool(params.Url)
				o.WriteEvent(request, " complete</tool>\n\n", isText, false)

				assistantMessage := openai.ChatCompletionMessage{
					Role:    openai.ChatMessageRoleAssistant,
					Content: "",
					ToolCalls: []openai.ToolCall{
						{
							ID:       toolCall.ID,
							Type:     toolCall.Type,
							Function: toolCall.Function, // Use the function from the tool call
						},
					},
				}

View on GitHub (pinned to fc36c76c05)

Solutions

  1. Validate/repair toolCall.Function.Arguments before unmarshalling (e.g. json.Valid check, accumulate chunks until complete)
  2. Use json.Unmarshal on a buffered full-arguments string rather than partial chunks; only parse once all delta chunks arrive
  3. Log the raw arguments (already included in the error) to confirm truncation and adjust max_tokens or prompt
  4. Fall back to skipping the bad tool call and continuing the stream instead of failing the whole request

Example fix

// before
if err := json.Unmarshal([]byte(toolCall.Function.Arguments), &params); err != nil {
    return fmt.Errorf("failed to unmarshal tool call arguments: %v, %s", err, toolCall.Function.Arguments)
}
// after
if !json.Valid([]byte(toolCall.Function.Arguments)) {
    o.WriteEvent(request, "\n\n<tool>Skipping malformed tool call</tool>\n\n", isText, false)
    continue
}
if err := json.Unmarshal([]byte(toolCall.Function.Arguments), &params); err != nil {
    continue
}
Defensive patterns

Strategy: validation

Validate before calling

args := toolCall.Function.Arguments
if !json.Valid([]byte(args)) {
    // skip or buffer more chunks before invoking the tool path
    return nil
}

Try / catch

if err := json.Unmarshal([]byte(toolCall.Function.Arguments), &params); err != nil {
    log.Warnf("bad tool args: %v raw=%s", err, toolCall.Function.Arguments)
    continue // skip malformed tool call, keep stream alive
}

Prevention

When it happens

Trigger: CreateChatCompletionStream receives a tool call named http_request whose Function.Arguments is truncated, invalid JSON (e.g. unescaped quotes in a URL), or empty; typically when the stream ends mid-tool-call or the model hallucinates bad JSON.

Common situations: Max-tokens cut off a tool call mid-arguments; low-quality/small models emitting malformed JSON; arguments containing characters that break JSON encoding; a provider change altering argument chunking.

Understand the failure class

Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.

Related errors


AI-assisted analysis of Billionmail/BillionMail@fc36c76c05 (2026-09-05). Data as JSON: /api/errors/eb5f7a2af7eaaca7. Report an issue: GitHub.