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

  1. Retry the request — a corrupted stream is usually transient.
  2. Inspect the accumulated raw buffer in the wrapped json error to find the exact syntax problem.
  3. Check for middleware/proxies or loggers that might alter or truncate SSE payloads.
  4. Verify no delta events were dropped in your SSE handler before FinalObject is called.
  5. 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

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


AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01). Data as JSON: /api/errors/8537dc5ff3013ea4. Report an issue: GitHub.