{"record":{"id":"67135563edb49359","repo":"charmbracelet/crush","slug":"error-parsing-parameters-s","errorCode":null,"errorMessage":"error parsing parameters: %s","messagePattern":"error parsing parameters: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/agent/tools/mcp/tools.go","lineNumber":39,"sourceCode":"type ToolResult struct {\n\tType      string\n\tContent   string\n\tData      []byte\n\tMediaType string\n}\n\nvar allTools = csync.NewMap[string, []*Tool]()\n\n// Tools returns all available MCP tools.\nfunc Tools() iter.Seq2[string, []*Tool] {\n\treturn allTools.Seq2()\n}\n\n// RunTool runs an MCP tool with the given input parameters.\nfunc RunTool(ctx context.Context, cfg *config.ConfigStore, name, toolName string, input string) (ToolResult, error) {\n\tvar args map[string]any\n\tif err := json.Unmarshal([]byte(input), &args); err != nil {\n\t\treturn ToolResult{}, fmt.Errorf(\"error parsing parameters: %s\", err)\n\t}\n\n\tc, err := getOrRenewClient(ctx, cfg, name)\n\tif err != nil {\n\t\treturn ToolResult{}, err\n\t}\n\tresult, err := c.CallTool(ctx, &mcp.CallToolParams{\n\t\tName:      toolName,\n\t\tArguments: args,\n\t})\n\tif err != nil {\n\t\treturn ToolResult{}, err\n\t}\n\n\tif len(result.Content) == 0 {\n\t\treturn ToolResult{Type: \"text\", Content: \"\"}, nil\n\t}\n","sourceCodeStart":21,"sourceCodeEnd":57,"githubUrl":"https://github.com/charmbracelet/crush/blob/7944b8e52225d8805e31eacbf7ef24856b0dfb7a/internal/agent/tools/mcp/tools.go#L21-L57","documentation":"RunTool is the entry point for invoking an MCP tool; it expects `input` to be a JSON object that unmarshals into map[string]any. If json.Unmarshal fails (malformed JSON, or valid JSON that is not an object such as an array or string), the parse error is returned as `error parsing parameters: ...` and the tool is never called.","triggerScenarios":"Calling mcp.RunTool (or the agent invoking an MCP tool) with input that is not a JSON object: raw text, truncated JSON, single quotes instead of double quotes, a JSON array or bare string, or unescaped newlines/control characters inside strings.","commonSituations":"LLM emits pseudo-JSON with trailing commas or comments; tool arguments built by string concatenation instead of marshalling; upstream caller passes the raw model output without validating it is an object first.","solutions":["Marshal arguments with json.Marshal from a map[string]any/struct instead of hand-building the JSON string","Validate the input parses as a JSON object before calling RunTool (json.Valid or an Unmarshal into map[string]any)","Strip markdown fences or prose the model may have wrapped around the JSON","Check for trailing commas/comments — Go's encoding/json rejects them; emit strict JSON"],"exampleFix":"// before\ninput := fmt.Sprintf(`{\"path\": %q}`, path) // breaks on quotes\n// after\nargs, _ := json.Marshal(map[string]any{\"path\": path})\nresult, err := mcp.RunTool(ctx, cfg, name, toolName, string(args))","handlingStrategy":"validation","validationCode":"var probe map[string]any\nif err := json.Unmarshal([]byte(input), &probe); err != nil {\n    return fmt.Errorf(\"tool input is not a JSON object: %w\", err)\n}\nresult, err := mcp.RunTool(ctx, cfg, name, toolName, input)","typeGuard":"func isJSONObject(s string) bool {\n    var m map[string]any\n    return json.Unmarshal([]byte(s), &m) == nil && m != nil\n}","tryCatchPattern":"result, err := mcp.RunTool(ctx, cfg, name, toolName, input)\nvar synthErr *json.SyntaxError\nif errors.As(err, &synthErr) || strings.HasPrefix(err.Error(), \"error parsing parameters\") {\n    // re-marshal arguments from a typed struct instead of retrying raw\n    input = mustMarshalJSON(argsStruct)\n    result, err = mcp.RunTool(ctx, cfg, name, toolName, input)\n}","preventionTips":["Always build tool arguments with json.Marshal, never string concatenation","Strip markdown code fences from model output before parsing","Reject trailing commas/comments — emit strict RFC 8259 JSON"],"tags":["json","mcp","parsing","parameters"],"backgroundTag":"invalid-json-input","analyzedSha":"7944b8e52225d8805e31eacbf7ef24856b0dfb7a","analyzedAt":"2026-08-29T12:48:59.079Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}