siyuan-note/siyuan · error

tool arguments are not valid JSON

Error message

tool arguments are not valid JSON: %w

What it means

parseToolArgs unmarshals the tool_call function arguments string produced by the model; if json.Unmarshal fails it wraps the JSON syntax error. Empty/whitespace arguments are tolerated (treated as an empty object), so only genuinely malformed JSON reaches this error.

Solutions

  1. Check the wrapped %w JSON syntax error to locate the malformed position
  2. Retry the request — truncation is often transient (stream cut)
  3. Inspect the raw arguments string logged from the model to confirm whether output was truncated
  4. Use a model/provider with more reliable tool-call JSON generation, or enable the provider's structured tool-call mode

Example fix

// before: model emits truncated JSON
{"query": "siyuan notes", "limit": 1
// after: complete valid JSON must be produced
{"query": "siyuan notes", "limit": 1}
Defensive patterns

Strategy: try-catch

Validate before calling

var probe map[string]any
if strings.TrimSpace(argsJSON) != "" && json.Unmarshal([]byte(argsJSON), &probe) != nil {
    // malformed arguments — repair or reject before invoking the tool
}

Type guard

func validArgsJSON(s string) bool {
    if strings.TrimSpace(s) == "" { return true }
    var m map[string]any
    return json.Unmarshal([]byte(s), &m) == nil && m != nil
}

Try / catch

args, err := parseToolArgs(tc.Function.Arguments)
if err != nil {
    return executedToolResult{Text: "invalid capability arguments: " + err.Error(), IsError: true}
}

Prevention

When it happens

Trigger: The model's streamed arguments JSON is truncated (stream cut off), contains a syntax error (unterminated string/brace, trailing comma, single quotes), or the arguments field was serialized incorrectly by a proxy/adapter.

Common situations: Network interruption mid-stream truncating the arguments buffer, weak small models emitting invalid JSON, middleman API adapters rewriting or chunking tool_call arguments incorrectly.

Understand the failure class

Background: JSON parse error: "Unexpected token" / "not valid JSON" / "failed to parse" — what JSON parsers are really complaining about — this error's family across 45 libraries.

Related errors


AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19). Data as JSON: /api/errors/a3a30a15c0e3138d. Report an issue: GitHub.

Appendix: source

Thrown at kernel/agent/tools.go:342

		return joined
	}
	if result.HasStructuredContent() {
		if data, err := json.Marshal(result.StructuredContent); err == nil {
			return string(data)
		}
	}
	return "(empty result)"
}

// parseToolArgs 在流结束后解析完整的工具参数,避免把损坏的 JSON 误报为缺少 schema 字段。
func parseToolArgs(argsJSON string) (map[string]any, error) {
	if strings.TrimSpace(argsJSON) == "" {
		return map[string]any{}, nil
	}

	var args map[string]any
	if err := json.Unmarshal([]byte(argsJSON), &args); err != nil {
		return nil, fmt.Errorf("tool arguments are not valid JSON: %w", err)
	}
	if args == nil {
		return nil, fmt.Errorf("tool arguments must be a JSON object")
	}
	return args, nil
}

View on GitHub (pinned to 9f775e8a12)