kataras/iris · error

makeHandler: func(...<T>) iris.Handler: expected %d function

Error message

makeHandler: func(...<T>) iris.Handler: expected %d function input parameters but fewer static dependencies matched (%d)

What it means

When a registered function returns an iris.Handler (handler-producing function), all of its input parameters must be resolvable as static dependencies at setup time (no request-time inputs allowed). If fewer static inputs than parameters matched, the container cannot call it and panics.

Source

Thrown at hero/handler.go:129

			}
		}
	}

	v := valueOf(fn)
	typ := v.Type()
	numIn := typ.NumIn()

	bindings := getBindingsForFunc(v, c.Dependencies, c.DisablePayloadAutoBinding, paramsCount)
	c.fillReport(context.HandlerName(fn), bindings)

	// Check if it's a function that accept zero or more dependencies
	// and returns an Iris Handler.
	if paramsCount <= 0 {
		// println(irisHandlerType.String())
		if typ.NumOut() == 1 && isIrisHandlerType(typ.Out(0)) {
			inputs := getStaticInputs(bindings, numIn)
			if len(inputs) != numIn {
				panic(fmt.Sprintf("makeHandler: func(...<T>) iris.Handler: expected %d function input parameters but fewer static dependencies matched (%d)", numIn, len(inputs)))
			}
			handler := v.Call(inputs)[0].Interface().(context.Handler)
			return handler
		}
	}

	resultHandler := defaultResultHandler
	for i, lidx := 0, len(c.resultHandlers)-1; i <= lidx; i++ {
		resultHandler = c.resultHandlers[lidx-i](resultHandler)
	}

	return func(ctx *context.Context) {
		inputs := make([]reflect.Value, numIn)

		for _, binding := range bindings {
			input, err := binding.Dependency.Handle(ctx, binding.Input)
			if err != nil {
				if err == ErrSeeOther {

View on GitHub (pinned to 7bedaf55a0)

Solutions

  1. Register every input type the factory needs: c.Register(a) etc., so all static inputs match.
  2. Remove request-scoped parameters from the factory; obtain them inside the returned handler instead.
  3. If the function should be a normal handler (request-time inputs), return nothing/handler-compatible signature rather than iris.Handler.
  4. Count parameters vs. registered bindings and align them.

Example fix

// before
func auth(s *Session) iris.Handler { ... } // Session not registered
// after
c.Register(sessionSvc)
func auth(s *SessionSvc) iris.Handler { ... }
Defensive patterns

Strategy: validation

Validate before calling

t := reflect.TypeOf(factoryFn)
for i := 0; i < t.NumIn(); i++ {
	if !isRegisteredStatic(t.In(i)) { panic("missing static binding: " + t.In(i).String()) }
}

Type guard

func isStaticHandlerFactory(fn any) bool {
	t := reflect.TypeOf(fn)
	return t.NumOut() == 1 && (t.Out(0) == irisHandlerType || t.Out(0) == irisHandlerFuncType)
}

Prevention

When it happens

Trigger: Registering func(a A, b B) iris.Handler where A or B has no static binding (unregistered type, or a dynamic/request-scoped dependency like a payload) via HandlerWithParams/MethodHandler.

Common situations: Middleware factories requiring request-scoped values (payloads, params) as inputs; forgetting to register one of the factory's dependency types; adding a new parameter to a factory without registering its type.

Related errors


AI-assisted analysis of kataras/iris@7bedaf55a0 (2026-08-30). Data as JSON: /api/errors/111dc8e7a141e11e. Report an issue: GitHub.