wavetermdev/waveterm · error
failed to unmarshal input: %w
Error message
failed to unmarshal input: %w
What it means
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.
Source
Thrown at pkg/aiusechat/tools_web.go:36
type WebNavigateToolInput struct {
WidgetId string `json:"widget_id"`
Url string `json:"url"`
}
func parseWebNavigateInput(input any) (*WebNavigateToolInput, error) {
result := &WebNavigateToolInput{}
if input == nil {
return nil, fmt.Errorf("input is required")
}
inputBytes, err := json.Marshal(input)
if err != nil {
return nil, fmt.Errorf("failed to marshal input: %w", err)
}
if err := json.Unmarshal(inputBytes, result); err != nil {
return nil, fmt.Errorf("failed to unmarshal input: %w", err)
}
if result.WidgetId == "" {
return nil, fmt.Errorf("widget_id is required")
}
if result.Url == "" {
return nil, fmt.Errorf("url is required")
}
return result, nil
}
func GetWebNavigateToolDefinition(tabId string) uctypes.ToolDefinition {
return uctypes.ToolDefinition{
Name: "web_navigate",
DisplayName: "Navigate Web Widget",View on GitHub (pinned to a4447c1563)
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.
Example fix
// 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"}) Defensive patterns
Strategy: type-guard
Validate before calling
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") } Type guard
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 != "" } Try / catch
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) } } Prevention
- 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.
When it happens
Trigger: 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).
Common situations: 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.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- input is required
- failed to marshal input: %w
- widget_id is required
- invalid value type for %s: %T
- failed to adapt type from %T => %T: %w
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/4f1af33d4a6cfcd5.
Report an issue: GitHub.