apache/pulsar · critical
function is nil
Error message
function is nil
What it means
pulsar-function-go wraps the user-supplied Go function into an internal `function` interface via newFunction. If the value passed to pf.Start() is nil, no valid handler can be built, so the library returns an errorHandler function that always yields this error instead of panicking at construction time. The failure surfaces when the instance actually starts and tries to process messages.
Source
Thrown at pulsar-function-go/pf/function.go:99
switch {
case handler.NumOut() > 2:
return fmt.Errorf("function may not return more than two values")
case handler.NumOut() > 1:
if !handler.Out(1).Implements(errorType) {
return fmt.Errorf("function returns two values, but the second does not implement error")
}
case handler.NumOut() == 1:
if !handler.Out(0).Implements(errorType) {
return fmt.Errorf("function returns a single value, but it does not implement error")
}
}
return nil
}
func newFunction(inputFunc interface{}) function {
if inputFunc == nil {
return errorHandler(fmt.Errorf("function is nil"))
}
handler := reflect.ValueOf(inputFunc)
handlerType := reflect.TypeOf(inputFunc)
if handlerType.Kind() != reflect.Func {
return errorHandler(fmt.Errorf("function kind %s is not %s", handlerType.Kind(), reflect.Func))
}
takesContext, err := validateArguments(handlerType)
if err != nil {
return errorHandler(err)
}
if err := validateReturns(handlerType); err != nil {
return errorHandler(err)
}
return pulsarFunction(func(ctx context.Context, input []byte) ([]byte, error) {
// construct argumentsView on GitHub (pinned to 820761864e)
Solutions
- Pass a non-nil function literal or named function to pf.Start(myFunc).
- Check the variable holding your handler before calling Start: if myFunc == nil { log.Fatal(...) }.
- If the handler comes from dynamic dispatch, ensure the registration/assignment path runs before Start.
Example fix
// before
var handler func(context.Context, []byte) ([]byte, error)
pf.Start(handler) // nil -> "function is nil"
// after
var handler func(context.Context, []byte) ([]byte, error) = actualHandler
if handler == nil {
log.Fatal("no function handler configured")
}
pf.Start(handler) Defensive patterns
Strategy: validation
Validate before calling
if fn == nil {
return fmt.Errorf("handler must be a non-nil func before calling pf.Start")
}
pf.Start(fn) Type guard
func isFunc(v interface{}) bool {
return v != nil && reflect.TypeOf(v).Kind() == reflect.Func
} Prevention
- Always pass a named function or function literal directly to pf.Start.
- Initialize handler variables at declaration, not lazily.
- Add a unit test asserting the handler variable is non-nil before startup.
When it happens
Trigger: Calling pf.Start(nil), or passing a nil func variable (e.g. a func obtained from config/flag that was never assigned).
Common situations: A variable holding the handler is conditionally assigned; a refactor renamed the handler function leaving a nil default; loading the handler dynamically and the lookup returned nil.
Related errors
- function kind %s is not %s
- start function failed, please check.
- config file is nil.
- No offloader found for driver '${driverName}'. Please make s
- Could not open configuration file
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/e6daea4e2400fbe6.
Report an issue: GitHub.