apache/pulsar · error
function takes two arguments, but the first is not Context.
Error message
function takes two arguments, but the first is not Context. got %s
What it means
When a Go function handler declares two input parameters, the framework requires the first to implement context.Context so it can inject the function context. Reflection checks argumentType.Implements(contextType); a non-Context first parameter fails registration with this error, reporting the parameter's reflect.Kind.
Source
Thrown at pulsar-function-go/pf/function.go:71
return output, nil
}
func errorHandler(e error) pulsarFunction {
return func(ctx context.Context, input []byte) ([]byte, error) {
return nil, e
}
}
func validateArguments(handler reflect.Type) (bool, error) {
handlerTakesContext := false
if handler.NumIn() > 2 {
return false, fmt.Errorf("functions may not take more than two arguments, but function takes %d", handler.NumIn())
} else if handler.NumIn() > 0 {
contextType := reflect.TypeOf((*context.Context)(nil)).Elem()
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) {View on GitHub (pinned to 820761864e)
Solutions
- Change the first parameter to ctx context.Context (and put the payload second).
- If no context is needed, use a single-parameter handler func(msg T).
- Ensure any custom context type embeds/implements context.Context.
- Adapt legacy signatures with a closure: func(ctx context.Context, msg []byte) { return legacy(msg, ...) }.
Example fix
// before
func handle(msg []byte, ctx *MyContext) ([]byte, error) { ... }
// after
func handle(ctx context.Context, msg []byte) ([]byte, error) { ... } Defensive patterns
Strategy: validation
Validate before calling
func takesContextFirst(handler interface{}) bool {
t := reflect.TypeOf(handler)
if t == nil || t.Kind() != reflect.Func || t.NumIn() == 0 {
return false
}
ctxType := reflect.TypeOf((*context.Context)(nil)).Elem()
if t.NumIn() == 1 {
return true // single-arg handlers are fine regardless
}
return t.In(0).Implements(ctxType)
} Type guard
func firstArgIsContext(handler interface{}) bool {
t := reflect.TypeOf(handler)
ctxType := reflect.TypeOf((*context.Context)(nil)).Elem()
return t.Kind() == reflect.Func && t.NumIn() > 1 && t.In(0).Implements(ctxType)
} Try / catch
f, err := pf.NewGoFunction(ctx, pf.GoFunction{
Handler: myHandler,
})
if err != nil {
if strings.Contains(err.Error(), "first is not Context") {
log.Fatalf("handler signature invalid: first parameter must be context.Context: %v", err)
}
log.Fatalf("function registration failed: %v", err)
} Prevention
- Always write two-argument handlers as (ctx context.Context, msg T) — ctx first, payload second.
- Use a single-argument handler if you don't need the context.
- Never swap parameter order; the check is positional.
- Add a unit test that constructs the function before deploying.
When it happens
Trigger: A handler like func handle(msg []byte, id int) or func handle(cfg Config, msg []byte) is passed to newFunction; NumIn() == 2 but the first parameter does not implement context.Context, so the signature is rejected.
Common situations: Writing handlers as (payload, metadata) instead of (ctx, payload); parameter order swapped; using a custom context type that does not implement context.Context; porting functions from other runtimes.
Related errors
- functions may not take more than two arguments, but function
- function may not return more than two values
- function returns two values, but the second does not impleme
- function returns a single value, but it does not implement e
- The specified go executable binary does not exist
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/dfe84a98d8bd7609.
Report an issue: GitHub.