wavetermdev/waveterm · error
Component function cannot b nil
Error message
Component function cannot b nil
What it means
validateCFunc performs reflection-based signature validation for functions passed to RegisterComponent. Its first check rejects a nil cfunc with "Component function cannot b nil" (note the typo 'b' is in the message). A nil component function cannot be invoked later when the frontend calls the component, so registration is refused immediately.
Source
Thrown at tsunami/engine/rootelem.go:238
defer r.atomLock.Unlock()
atom, ok := r.Atoms[name]
if !ok {
return fmt.Errorf("atom %q not found", name)
}
return atom.SetVal(val)
}
func (r *RootElem) RemoveAtom(name string) {
r.atomLock.Lock()
defer r.atomLock.Unlock()
delete(r.Atoms, name)
}
func validateCFunc(cfunc any) error {
if cfunc == nil {
return fmt.Errorf("Component function cannot b nil")
}
rval := reflect.ValueOf(cfunc)
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 {View on GitHub (pinned to a4447c1563)
Solutions
- Ensure the function is defined and assigned before calling RegisterComponent
- Check whatever produces the handler for nil returns (map lookups, config-driven wiring)
- Wrap registration in an error check and fail fast at startup rather than at render time
Example fix
// before
var handler func(map[string]any) any
root.RegisterComponent("counter", handler) // handler still nil
// after
handler := func(m map[string]any) any { return nil }
if err := root.RegisterComponent("counter", handler); err != nil { return err } Defensive patterns
Strategy: validation
Validate before calling
if cfunc == nil {
return fmt.Errorf("component %q: handler is nil", name)
}
if err := root.RegisterComponent(name, cfunc); err != nil { return err } Type guard
func isNotNilFunc(v any) bool {
if v == nil { return false }
rv := reflect.ValueOf(v)
return rv.Kind() == reflect.Func && !rv.IsNil()
} Try / catch
if err := root.RegisterComponent("counter", cfunc); err != nil {
return fmt.Errorf("register component failed: %w", err)
} Prevention
- Fail fast at startup: register all components in init and check every error
- When handlers come from lookups, check for nil before registering
- Avoid untyped nil interface variables when wiring handlers from config
When it happens
Trigger: RegisterComponent(name, nil); passing an untyped nil interface variable that was never assigned; a typed-nil value such as a nil func variable actually passes this check (it is not interface-nil) but is caught later.
Common situations: A factory/lookup returned nil (e.g. a map miss producing a nil handler) and the result was registered unchecked; wiring a component function from config where the key was absent.
Related errors
- Component function must be a function
- Component function must take exactly 1 argument
- beginning of file
- procinfo: process not found
- integer overflow
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/2b8cb2ea6b63a4d8.
Report an issue: GitHub.