gofiber/fiber · critical

fiber: Config.RegexHandler must have signature func(string)…

Error message

fiber: Config.RegexHandler must have signature func(string) T

What it means

validateRegexHandler requires the handler to have exactly one input of type string and one output. Any other arity or input type triggers this panic at app init. The expected shape is func(string) T where T implements regexMatcher.

Solutions

  1. Make the handler exactly func(string) <T> with one input (string) and one output.
  2. Close over any extra configuration rather than adding parameters.
  3. Handle compile errors inside the function (return a sentinel matcher) rather than via a second return value.

Example fix

// before
RegexHandler: func(p string, flags string) (*regexp.Regexp, error) { ... }

// after
flags := "(?i)"
RegexHandler: func(p string) *regexp.Regexp {
  return regexp.MustCompile(flags + p)
}
Defensive patterns

Strategy: validation

Validate before calling

// Assert the handler signature is func(string) T
func assertRegexHandlerSig(h any) error {
    ht := reflect.ValueOf(h).Type()
    if ht.NumIn() != 1 || ht.In(0).Kind() != reflect.String {
        return errors.New("need exactly one string input")
    }
    if ht.NumOut() != 1 { return errors.New("need exactly one output") }
    return nil
}

Type guard

func isStringInOneOut(h any) bool {
    ht := reflect.ValueOf(h).Type()
    return ht.NumIn() == 1 && ht.In(0).Kind() == reflect.String && ht.NumOut() == 1
}

Prevention

When it happens

Trigger: Config.RegexHandler is func(pattern string, flags string) *regexp.Regexp (two inputs), func() *regexp.Regexp (zero inputs), func(string) (*regexp.Regexp, error) (two outputs), or func(int) *regexp.Regexp (wrong input type).

Common situations: Wrapping regexp.MustCompile with extra config args; returning (matcher, error) for compile errors; refactor that added parameters.

Related errors


AI-assisted analysis of gofiber/fiber@a105acad6c (2026-08-11). Data as JSON: /api/errors/57621590492a80e5. Report an issue: GitHub.

Appendix: source

Thrown at constraint.go:61

		panic("fiber: Config.RegexHandler return type must support MatchString(string) bool")
	}
	if isNilRegexMatcher(matcher) {
		panic("fiber: Config.RegexHandler must not return nil")
	}
	return matcher
}

func validateRegexHandler(handler any) any {
	if handler == nil {
		return regexp.MustCompile
	}
	handlerValue := reflect.ValueOf(handler)
	handlerType := handlerValue.Type()
	if handlerType.Kind() != reflect.Func || handlerValue.IsNil() {
		panic("fiber: Config.RegexHandler must be a non-nil function")
	}
	if handlerType.NumIn() != 1 || handlerType.In(0) != stringType || handlerType.NumOut() != 1 {
		panic("fiber: Config.RegexHandler must have signature func(string) T")
	}
	if !handlerType.Out(0).Implements(regexMatcherType) {
		panic("fiber: Config.RegexHandler return type must support MatchString(string) bool")
	}
	return handler
}

// ConstraintHandler is the interface that all constraints must implement.
// Built-in and custom constraints are treated uniformly through this interface.
type ConstraintHandler interface {
	// Name returns the constraint identifier used in route patterns (e.g. "int", "minLen", "regex").
	Name() string

	// Execute validates a request parameter value against the constraint.
	// param is the request parameter value to check.
	// data contains the pre-typed constraint data produced by Analyze() at registration time.
	Execute(param string, data []any) bool
}

View on GitHub (pinned to a105acad6c)