{"record":{"id":"b5f4cb8f566ef535","repo":"wavetermdev/waveterm","slug":"widget-id-is-required-b5f4cb","errorCode":null,"errorMessage":"widget_id is required","messagePattern":"widget_id is required","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/aiusechat/tools_web.go","lineNumber":40,"sourceCode":"\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\",\n\t\tDescription: \"Navigate a web browser widget to a new URL\",\n\t\tToolLogName: \"web:navigate\",\n\t\tStrict:      true,\n\t\tInputSchema: map[string]any{","sourceCodeStart":22,"sourceCodeEnd":58,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/aiusechat/tools_web.go#L22-L58","documentation":"After successfully decoding the input into WebNavigateToolInput, the parser validates that widget_id is a non-empty string. The web_navigate tool needs the 8-character widget ID to locate the target web browser widget block, so a missing or empty widget_id is rejected. This catches arguments the JSON schema did not enforce (or that the model omitted while still providing url).","triggerScenarios":"The web_navigate callback receives input where the widget_id field is absent or the empty string, e.g. {\"url\": \"https://example.com\"} or {\"widget_id\": \"\", \"url\": \"...\"}.","commonSituations":"The model omits widget_id because it does not know the widget's 8-character ID; the harness sends a partially-filled struct; a template or script generates the call with an unfilled placeholder.","solutions":["Re-issue the tool call including the widget's 8-character widget_id (visible in the Wave Terminal UI / block list).","List available web widgets first (via the AI tools that enumerate blocks/widgets) to obtain the correct widget_id before navigating.","Tighten the tool InputSchema (required: [\"widget_id\",\"url\"], minLength: 8 for widget_id) so the model is forced to supply it.","If the widget was closed, its ID is stale - reopen a web widget and use the new ID."],"exampleFix":"// before: callback(map[string]any{\"url\": \"https://example.com\"}) returns 'widget_id is required'; // after: callback(map[string]any{\"widget_id\": \"AB12CD34\", \"url\": \"https://example.com\"})","handlingStrategy":"validation","validationCode":"m, ok := input.(map[string]any); if !ok { return errors.New(\"input must be an object\") }; wid, _ := m[\"widget_id\"].(string); if wid == \"\" { return errors.New(\"widget_id is required\") }","typeGuard":"func hasWidgetID(input any) bool { m, ok := input.(map[string]any); if !ok { return false }; w, ok := m[\"widget_id\"].(string); return ok && w != \"\" }","tryCatchPattern":"parsed, err := parseWebNavigateInput(input); if err != nil && strings.Contains(err.Error(), \"widget_id is required\") { /* ask the model to supply the 8-character widget id, or list widgets for it */ }","preventionTips":["Ensure required: [widget_id, url] is present in the tool InputSchema.","Provide the model the list of web widget IDs in context so it can fill widget_id.","Validate widget_id length (8 chars) before calling to catch truncated IDs.","Handle closed widgets: refresh the widget list if a formerly valid ID stops working."],"tags":["validation","required-field","web","tool-call"],"backgroundTag":"missing-required-argument","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}