wavetermdev/waveterm · error
Map argument must be map[string]any
Error message
Map argument must be map[string]any
What it means
If the component function's single argument is a map, validateCFunc requires it to be exactly map[string]any (string keys, empty-interface values, no methods on the element type). Any other map shape — e.g. map[string]string or map[string]int — is rejected with "Map argument must be map[string]any". Pointer-to-map arguments are dereferenced before this check.
Source
Thrown at tsunami/engine/rootelem.go:259
if rval.Kind() != reflect.Func {
return fmt.Errorf("Component function must be a function")
}
rtype := rval.Type()
if rtype.NumIn() != 1 {
return fmt.Errorf("Component function must take exactly 1 argument")
}
if rtype.NumOut() != 1 {
return fmt.Errorf("Component function must return exactly 1 value")
}
// first argument can be a map[string]any, or a struct, or ptr to struct (we'll reflect the value into it)
arg1Type := rtype.In(0)
if arg1Type.Kind() == reflect.Ptr {
arg1Type = arg1Type.Elem()
}
if arg1Type.Kind() == reflect.Map {
if arg1Type.Key().Kind() != reflect.String ||
!(arg1Type.Elem().Kind() == reflect.Interface && arg1Type.Elem().NumMethod() == 0) {
return fmt.Errorf("Map argument must be map[string]any")
}
} else if arg1Type.Kind() != reflect.Struct &&
!(arg1Type.Kind() == reflect.Interface && arg1Type.NumMethod() == 0) {
return fmt.Errorf("Component function argument must be map[string]any, struct, or any")
}
return nil
}
func (r *RootElem) RegisterComponent(name string, cfunc any) error {
if err := validateCFunc(cfunc); err != nil {
return err
}
r.CFuncs[name] = cfunc
return nil
}
func callVDomFn(fnVal any, data vdom.VDomEvent) {
if fnVal == nil {View on GitHub (pinned to a4447c1563)
Solutions
- Change the parameter type to map[string]any and convert inside the function body
- If you want type safety, use a struct parameter instead of a typed map
- Remove named/aliased map types in favor of the literal map[string]any
Example fix
// before
root.RegisterComponent("table", func(cols map[string]string) any { ... })
// after
root.RegisterComponent("table", func(props map[string]any) any {
cols := toStringMap(props["cols"]) // convert inside
return renderTable(cols)
}) Defensive patterns
Strategy: validation
Validate before calling
t := reflect.TypeOf(cfunc)
if t != nil && t.Kind() == reflect.Func && t.NumIn() == 1 {
at := t.In(0)
if at.Kind() == reflect.Ptr { at = at.Elem() }
if at.Kind() == reflect.Map && (at.Key().Kind() != reflect.String || at.Elem().Kind() != reflect.Interface) {
return fmt.Errorf("map param must be map[string]any, got %v", t.In(0))
}
} Type guard
func takesMapStringAny(v any) bool {
t := reflect.TypeOf(v)
if t == nil || t.Kind() != reflect.Func || t.NumIn() != 1 { return false }
at := t.In(0)
if at.Kind() == reflect.Ptr { at = at.Elem() }
return at.Kind() == reflect.Map && at.Key().Kind() == reflect.String &&
at.Elem().Kind() == reflect.Interface && at.Elem().NumMethod() == 0
} Try / catch
if err := root.RegisterComponent(name, fn); err != nil {
return fmt.Errorf("map param must be map[string]any: %w", err)
} Prevention
- Use the literal type map[string]any for props maps, never typed maps
- Prefer struct parameters when you want compile-time key/value typing
- Convert typed maps inside the function body, not in its signature
When it happens
Trigger: RegisterComponent with func(map[string]string) any; func(map[string]interface{}) on a named map type whose element is not plain any; a custom key type like map[int]any.
Common situations: Declaring typed maps to get compile-time safety, not realizing the reflection contract demands map[string]any; passing an aliased map type whose element kind is not empty interface.
Related errors
- Component function must take exactly 1 argument
- Component function must return exactly 1 value
- Component function argument must be map[string]any, struct,
- invalid number type %s
- invalid argument type %s
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/0ac5c3a167b1ca0c.
Report an issue: GitHub.