wavetermdev/waveterm · error
invalid accumulated tool input JSON: %w
Error message
invalid accumulated tool input JSON: %w
What it means
FinalObject on the streaming partialJSON accumulator validates the accumulated tool_use input before emitting it. The streamed input_json_delta chunks must concatenate into valid JSON; when the accumulated buffer fails json.Unmarshal, this error is returned. It indicates corrupted or incomplete tool argument streaming.
Source
Thrown at pkg/aiusechat/anthropic/anthropic-backend.go:335
// The stream may send empty "" chunks; ignore if zero-length
if s == "" {
return
}
p.buf.WriteString(s)
}
func (p *partialJSON) Bytes() []byte { return p.buf.Bytes() }
func (p *partialJSON) FinalObject() (json.RawMessage, error) {
raw := p.buf.Bytes()
// If empty, treat as "{}"
if len(bytes.TrimSpace(raw)) == 0 {
return json.RawMessage(`{}`), nil
}
// The accumulated content should be a valid JSON object string; parse it.
var v interface{}
if err := json.Unmarshal(raw, &v); err != nil {
return nil, fmt.Errorf("invalid accumulated tool input JSON: %w", err)
}
// Ensure it's an object per Anthropic contract
switch v.(type) {
case map[string]interface{}:
return json.RawMessage(raw), nil
default:
return nil, fmt.Errorf("tool input is not an object")
}
}
// sanitizeHostnameInError removes the Wave cloud hostname from error messages
func sanitizeHostnameInError(err error) error {
if err == nil {
return nil
}
errStr := err.Error()
parsedURL, parseErr := url.Parse(uctypes.DefaultAIEndpoint)
if parseErr == nil && parsedURL.Host != "" && strings.Contains(errStr, parsedURL.Host) {View on GitHub (pinned to a4447c1563)
Solutions
- Retry the request — a corrupted stream is usually transient.
- Inspect the accumulated raw buffer in the wrapped json error to find the exact syntax problem.
- Check for middleware/proxies or loggers that might alter or truncate SSE payloads.
- Verify no delta events were dropped in your SSE handler before FinalObject is called.
- If reproducible with a specific model/request, report/upstream since the provider emitted invalid JSON.
Example fix
// handling pattern
raw, err := acc.FinalObject()
if err != nil {
log.Printf("tool input corrupted, retrying: %v", err)
return runStep(ctx) // retry the stream
} Defensive patterns
Strategy: retry
Validate before calling
// after accumulation, before use:
var probe interface{}
if err := json.Unmarshal(raw, &probe); err != nil {
log.Printf("stream corrupted: %v", err) // then retry the request
} Type guard
func isValidJSON(raw []byte) bool { var v interface{}; return json.Unmarshal(raw, &v) == nil } Try / catch
input, err := acc.FinalObject()
if err != nil {
var jerr *json.SyntaxError
if errors.As(err, &jerr) {
return retryChatStep(ctx) // transient stream corruption
}
return err
} Prevention
- Retry streaming requests on mid-stream failures
- Ensure SSE handlers never drop or reorder input_json_delta events
- Audit proxies/interceptors that might rewrite response bodies
- Log accumulated raw buffers on failure to detect systematic providers issues
When it happens
Trigger: During an Anthropic streaming response, the concatenated input_json_delta fragments for a tool_use block do not form valid JSON when FinalObject is called — e.g. deltas dropped mid-stream, invalid control characters in the JSON, or a provider-side truncation.
Common situations: Network interruptions truncating the SSE stream; upstream Anthropic API errors that cut tool input mid-JSON; custom/intercepting proxies mangling the body; client bug in reassembling delta chunks.
Related errors
- tool input is not an object
- tool result missing ToolUseID
- tool call with ID %s not found in chat %s
- msg.error
- sse handler is nil
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/8537dc5ff3013ea4.
Report an issue: GitHub.