wavetermdev/waveterm · error
Component function argument must be map[string]any, struct,
Error message
Component function argument must be map[string]any, struct, or any
What it means
The component function's single argument must be one of: map[string]any, a struct, a pointer to struct, or any (empty interface). Anything else — slices, primitives like string/int, channels, funcs — fails this final check with "Component function argument must be map[string]any, struct, or any".
Source
Thrown at tsunami/engine/rootelem.go:263
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 {
return
}
fn := fnVal
if vdf, ok := fnVal.(*vdom.VDomFunc); ok {View on GitHub (pinned to a4447c1563)
Solutions
- Change the parameter to map[string]any, a struct, *struct, or any
- Encode list-like props as fields inside a struct or as values in a map[string]any
- Wrap the existing function in a closure with an accepted parameter type
Example fix
// before
root.RegisterComponent("list", func(items []string) any { ... }) // slice not allowed
// after
type listProps struct { Items []string `json:"items"` }
root.RegisterComponent("list", func(p *listProps) any { return renderList(p.Items) }) 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() }
ok := at.Kind() == reflect.Map || at.Kind() == reflect.Struct ||
(at.Kind() == reflect.Interface && at.NumMethod() == 0)
if !ok { return fmt.Errorf("param type %v not allowed", t.In(0)) }
} Type guard
func hasValidComponentParam(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() }
if at.Kind() == reflect.Map { return at.Key().Kind() == reflect.String && at.Elem().Kind() == reflect.Interface }
return at.Kind() == reflect.Struct || (at.Kind() == reflect.Interface && at.NumMethod() == 0)
} Try / catch
if err := root.RegisterComponent(name, fn); err != nil {
return fmt.Errorf("component %s param must be map[string]any/struct/any: %w", name, err)
} Prevention
- Accept only map[string]any, struct, *struct, or any as the props parameter
- Move slices/primitives into struct fields or map entries
- Validate all component signatures in a startup test to catch regressions early
When it happens
Trigger: RegisterComponent with func(props []string) any; func(count int) any; func(cb func() string) any; any single-parameter function whose parameter is not a (pointer to) struct, map[string]any, or empty interface.
Common situations: Registering helper functions that take primitive options; expecting the engine to marshal arbitrary JSON types into slices; aliasing a parameter type that resolves to a slice or primitive.
Related errors
- Component function must take exactly 1 argument
- Component function must return exactly 1 value
- Map argument must be map[string]any
- invalid number type %s
- invalid argument type %s
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/f849a4403eddabc5.
Report an issue: GitHub.