{"record":{"id":"859a73db2f99dca4","repo":"alibaba/open-code-review","slug":"invalid-tool-call-arguments-for-s-w","errorCode":null,"errorMessage":"invalid tool call arguments for %s: %w","messagePattern":"invalid tool call arguments for (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/llm/client.go","lineNumber":1288,"sourceCode":"\t\tcase \"assistant\":\n\t\t\tflushToolResults()\n\t\t\t// Reuse the native MessageParam whole to preserve thinking blocks\n\t\t\t// and signatures. Copy the slice to avoid mutating shared state\n\t\t\t// when the cache_control breakpoint writes below.\n\t\t\tif native, ok := msg.Native.Payload.(anthropic.MessageParam); ok && len(native.Content) > 0 {\n\t\t\t\tnative.Content = append([]anthropic.ContentBlockParamUnion(nil), native.Content...)\n\t\t\t\tmessages = append(messages, native)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tvar blocks []anthropic.ContentBlockParamUnion\n\t\t\tif s, ok := msg.Content.(string); ok && s != \"\" {\n\t\t\t\tblocks = append(blocks, anthropic.NewTextBlock(s))\n\t\t\t}\n\t\t\tfor _, tc := range msg.ToolCalls {\n\t\t\t\targsMap := map[string]any{}\n\t\t\t\tif tc.Function.Arguments != \"\" {\n\t\t\t\t\tif err := json.Unmarshal([]byte(tc.Function.Arguments), &argsMap); err != nil {\n\t\t\t\t\t\treturn anthropic.MessageNewParams{}, fmt.Errorf(\"invalid tool call arguments for %s: %w\", tc.Function.Name, err)\n\t\t\t\t\t}\n\t\t\t\t\tif argsMap == nil {\n\t\t\t\t\t\t// null arguments → empty map; Anthropic API rejects\n\t\t\t\t\t\t// null input (#382). Same guard as llmloop.parseToolArgs.\n\t\t\t\t\t\targsMap = map[string]any{}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tblocks = append(blocks, anthropic.NewToolUseBlock(tc.ID, argsMap, tc.Function.Name))\n\t\t\t}\n\t\t\tif len(blocks) > 0 {\n\t\t\t\tmessages = append(messages, anthropic.NewAssistantMessage(blocks...))\n\t\t\t} else {\n\t\t\t\ts, _ := msg.Content.(string)\n\t\t\t\tmessages = append(messages, anthropic.NewAssistantMessage(anthropic.NewTextBlock(s)))\n\t\t\t}\n\t\tdefault:\n\t\t\tflushToolResults()\n\t\t\tswitch content := msg.Content.(type) {","sourceCodeStart":1270,"sourceCodeEnd":1306,"githubUrl":"https://github.com/alibaba/open-code-review/blob/5cf97d0d15cbd41b602513c4be3bfec3cee5bf7f/internal/llm/client.go#L1270-L1306","documentation":"Raised while converting OpenAI-style tool calls to the Anthropic message format. Tool-call function arguments arrive as a JSON string and must be unmarshaled into a map; if the string is non-empty but not valid JSON the conversion aborts with this error wrapping the json.Unmarshal failure. A valid-JSON `null` is accepted and treated as an empty input map (Anthropic rejects null input).","triggerScenarios":"Building an anthropic.MessageNewParams from a message whose ToolCalls entry has Function.Arguments that is non-empty but not valid JSON — truncated JSON, single quotes, trailing commas, or a model emitting plain text as arguments.","commonSituations":"Malformed tool-call arguments produced by a model or upstream provider; arguments built by hand without json.Marshal; logs or fixtures pasted back as arguments; truncation at buffer boundaries.","solutions":["Inspect tc.Function.Arguments and fix the source producing invalid JSON","Always generate arguments with json.Marshal(map[string]any{...}) rather than string concatenation","Validate with json.Valid before passing the message through","Use `null` or an empty object instead of a malformed string for no-argument tool calls"],"exampleFix":"// before\nargs := `{'path': 'x.go'}` // not valid JSON\n// after\nargsBytes, _ := json.Marshal(map[string]any{\"path\": \"x.go\"})\nargs := string(argsBytes)","handlingStrategy":"validation","validationCode":"func validToolArgs(args string) bool {\n\tif args == \"\" || args == \"null\" { return true }\n\tvar m map[string]any\n\treturn json.Unmarshal([]byte(args), &m) == nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always build arguments with json.Marshal, never string concatenation","Run json.Valid() on model-generated arguments before replaying them","Treat \"null\" as an empty map explicitly","Log raw arguments when a parse fails so upstream model bugs are visible"],"tags":["json","tool-calls","anthropic","serialization"],"backgroundTag":"invalid-json-arguments","analyzedSha":"5cf97d0d15cbd41b602513c4be3bfec3cee5bf7f","analyzedAt":"2026-09-02T02:08:09.116Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}