{"record":{"id":"4f1af33d4a6cfcd5","repo":"wavetermdev/waveterm","slug":"failed-to-unmarshal-input-w-4f1af3","errorCode":null,"errorMessage":"failed to unmarshal input: %w","messagePattern":"failed to unmarshal input: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/aiusechat/tools_web.go","lineNumber":36,"sourceCode":"type WebNavigateToolInput struct {\n\tWidgetId string `json:\"widget_id\"`\n\tUrl      string `json:\"url\"`\n}\n\nfunc parseWebNavigateInput(input any) (*WebNavigateToolInput, error) {\n\tresult := &WebNavigateToolInput{}\n\n\tif input == nil {\n\t\treturn nil, fmt.Errorf(\"input is required\")\n\t}\n\n\tinputBytes, err := json.Marshal(input)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to marshal input: %w\", err)\n\t}\n\n\tif err := json.Unmarshal(inputBytes, result); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to unmarshal input: %w\", err)\n\t}\n\n\tif result.WidgetId == \"\" {\n\t\treturn nil, fmt.Errorf(\"widget_id is required\")\n\t}\n\n\tif result.Url == \"\" {\n\t\treturn nil, fmt.Errorf(\"url is required\")\n\t}\n\n\treturn result, nil\n}\n\nfunc GetWebNavigateToolDefinition(tabId string) uctypes.ToolDefinition {\n\n\treturn uctypes.ToolDefinition{\n\t\tName:        \"web_navigate\",\n\t\tDisplayName: \"Navigate Web Widget\",","sourceCodeStart":18,"sourceCodeEnd":54,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/aiusechat/tools_web.go#L18-L54","documentation":"This error wraps a json.Unmarshal failure when the (re-marshaled) input bytes cannot be decoded into WebNavigateToolInput{WidgetId, Url string}. It fires when fields have the wrong JSON types - e.g. widget_id given as a number or url as an object - because Unmarshal is strict about string fields. The underlying type error is preserved via %w.","triggerScenarios":"The web_navigate tool receives input where widget_id or url is not a JSON string (number, bool, array, object) or where the input is valid JSON but of an incompatible shape (e.g. a bare string or array instead of an object).","commonSituations":"LLM emits widget_id as a numeric id or nests the fields (input: {\"widget_id\": {\"id\": \"...\"}}); harness passes a pre-typed struct that marshals to a different shape; schema enforcement disabled so malformed arguments reach the callback.","solutions":["Read the wrapped error to see which field has the wrong type, then correct the tool call so widget_id and url are plain strings.","Re-enable or tighten the tool's InputSchema (type: string for both fields, additionalProperties: false) so the model cannot emit wrong-typed values.","In the caller, coerce/validate types before invoking (e.g. convert numeric ids to their 8-character string form).","If passing a struct programmatically, confirm its JSON tags produce {\"widget_id\": ..., \"url\": ...}.","Return the specific *json.UnmarshalTypeError field info back to the model so it can self-correct."],"exampleFix":"// before: callback(map[string]any{\"widget_id\": 12345, \"url\": \"https://example.com\"}) fails with 'cannot unmarshal number into Go struct field .widget_id of type string'; // after: callback(map[string]any{\"widget_id\": \"AB12CD34\", \"url\": \"https://example.com\"})","handlingStrategy":"type-guard","validationCode":"m, ok := input.(map[string]any); if !ok { return errors.New(\"web_navigate input must be an object\") }; if _, ok := m[\"widget_id\"].(string); !ok { return errors.New(\"widget_id must be a string\") }; if _, ok := m[\"url\"].(string); !ok { return errors.New(\"url must be a string\") }","typeGuard":"func validWebNavigateInput(input any) bool { m, ok := input.(map[string]any); if !ok { return false }; w, okW := m[\"widget_id\"].(string); u, okU := m[\"url\"].(string); return okW && okU && w != \"\" && u != \"\" }","tryCatchPattern":"parsed, err := parseWebNavigateInput(input); if err != nil { var typeErr *json.UnmarshalTypeError; if errors.As(err, &typeErr) { return nil, fmt.Errorf(\"field %s has wrong type: %w\", typeErr.Field, err) } }","preventionTips":["Keep the InputSchema strict (type: string for both fields, additionalProperties: false) so models emit correct types.","Coerce numeric widget ids to their 8-character string form before calling.","Validate input shape in the harness with a type guard before the callback.","Return the wrapped *json.UnmarshalTypeError field info back to the model for self-correction."],"tags":["json","type-mismatch","validation","web"],"backgroundTag":"schema-validation-failed","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}