apache/pulsar · critical

function kind is not

Error message

function kind %s is not %s

What it means

newFunction uses reflection to verify that the value passed to pf.Start() is actually a func. If Start receives any other kind of value (string, struct, int, etc.), the library returns an errorHandler that produces this formatted error, naming the offending reflect.Kind.

Solutions

  1. Pass the function itself, not a string name or struct: pf.Start(myFunc).
  2. Verify the argument's Go type is a func before calling Start.
  3. If dispatching by name, resolve the name to a func value first (e.g. a map[string]func(...)).

Example fix

// before
pf.Start("myHandler") // kind string is not func
// after
pf.Start(myHandler)
Defensive patterns

Strategy: validation

Validate before calling

if reflect.TypeOf(arg) == nil || reflect.TypeOf(arg).Kind() != reflect.Func {
    return fmt.Errorf("pf.Start requires a func, got %T", arg)
}
pf.Start(arg)

Type guard

func isFuncValue(v interface{}) bool {
    t := reflect.TypeOf(v)
    return t != nil && t.Kind() == reflect.Func
}

Prevention

When it happens

Trigger: Calling pf.Start() with a non-func value, e.g. pf.Start("myHandler") or pf.Start(someStruct), or an untyped nil interface wrapped in a struct field.

Common situations: Config-driven dispatch where the wrong variable is passed (config value instead of the function); type changes after refactors; misunderstanding that Start expects the function itself, not its name.

Related errors


AI-assisted analysis of apache/pulsar@820761864e (2026-09-06). Data as JSON: /api/errors/a7db1af46099e647. Report an issue: GitHub.

Appendix: source

Thrown at pulsar-function-go/pf/function.go:104

			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 arguments
		var args []reflect.Value
		if takesContext {
			args = append(args, reflect.ValueOf(ctx))
		}

View on GitHub (pinned to 820761864e)