apache/pulsar · error
function returns two values, but the second does not impleme
Error message
function returns two values, but the second does not implement error
What it means
For two-value handlers, the second return value must implement the error interface — the framework's (result, error) convention mirrors idiomatic Go. Reflection checks handler.Out(1).Implements(errorType); anything else (string, custom non-error type) fails registration.
Source
Thrown at pulsar-function-go/pf/function.go:86
argumentType := handler.In(0)
handlerTakesContext = argumentType.Implements(contextType)
if handler.NumIn() > 1 && !handlerTakesContext {
return false, fmt.Errorf("function takes two arguments, but the first is not Context. got %s", argumentType.Kind())
}
}
return handlerTakesContext, nil
}
func validateReturns(handler reflect.Type) error {
errorType := reflect.TypeOf((*error)(nil)).Elem()
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))View on GitHub (pinned to 820761864e)
Solutions
- Make the second return value type error (return nil on success).
- Define custom error types so they implement error (add an Error() string method).
- If the second value is data, reorder so data is first and error second, or drop it.
- Wrap error-code strings into errors.New / fmt.Errorf.
Example fix
// before
func handle(ctx context.Context, msg []byte) ([]byte, string) { ... }
// after
func handle(ctx context.Context, msg []byte) ([]byte, error) {
if bad { return nil, fmt.Errorf("bad message") }
...
} Defensive patterns
Strategy: type-guard
Validate before calling
func secondReturnIsError(handler interface{}) bool {
t := reflect.TypeOf(handler)
errType := reflect.TypeOf((*error)(nil)).Elem()
return t.Kind() == reflect.Func && t.NumOut() == 2 && t.Out(1).Implements(errType)
} Type guard
func hasErrorSecond(handler interface{}) bool {
t := reflect.TypeOf(handler)
errType := reflect.TypeOf((*error)(nil)).Elem()
return t.NumOut() > 1 && t.Out(1).Implements(errType)
} Try / catch
f, err := pf.NewGoFunction(ctx, pf.GoFunction{
Handler: myHandler,
})
if err != nil {
if strings.Contains(err.Error(), "second does not implement error") {
log.Fatalf("change second return value to type error: %v", err)
}
log.Fatalf("function registration failed: %v", err)
} Prevention
- Always end handler signatures with error as the last return value.
- Make custom error types implement Error() string so they satisfy the error interface.
- Never return status strings or code ints in the error position.
- Grep handlers for return statements missing a trailing error during code review.
When it happens
Trigger: A handler like func(ctx context.Context, msg []byte) ([]byte, string) or ([]byte, MyStatus) is registered; NumOut()==2 but Out(1) does not implement error.
Common situations: Returning a status/error code string instead of error; returning (value, value) pairs; custom error-like struct that does not implement the built-in error interface; accidentally swapping return order.
Related errors
- function returns a single value, but it does not implement e
- functions may not take more than two arguments, but function
- function takes two arguments, but the first is not Context.
- function may not return more than two values
- The specified go executable binary does not exist
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/2f9d0cc12e789a64.
Report an issue: GitHub.