gofiber/fiber · error

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

Error message

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

What it means

Panics from constraint.go:61 inside validateRegexHandler when RegexHandler is a function but its signature is not exactly func(string) T (one string input, one output). The checks are NumIn()!=1, In(0)!=string, or NumOut()!=1. Validation happens at construction and route parsing.

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 9a4c7e57fe)

Solutions

  1. Keep the signature func(string) T; prefer assigning regexp.MustCompile directly.
  2. If you need regexp.Compile's error, wrap it to panic or log+fallback so the signature stays single-return.
  3. Use a typed adapter that preserves the func(string) *regexp.Regexp shape.

Example fix

// before
app := fiber.New(fiber.Config{
    RegexHandler: regexp.Compile, // returns (*Regexp, error) -> 2 outputs
})

// after
app := fiber.New(fiber.Config{
    RegexHandler: func(p string) *regexp.Regexp {
        re, err := regexp.Compile(p)
        if err != nil {
            panic(err)
        }
        return re
    },
})
Defensive patterns

Strategy: type-guard

Type guard

func hasRegexHandlerSignature(h any) bool {
    ht := reflect.ValueOf(h).Type()
    return ht.NumIn() == 1 && ht.In(0) == reflect.TypeFor[string]() && ht.NumOut() == 1
}

Prevention

When it happens

Trigger: A handler taking the wrong input type: func(int) *regexp.Regexp; a handler with no return: func(string); a handler with extra inputs or outputs; or a named input type that is not string (func(regexPattern) *regexp.Regexp).

Common situations: Wrapping MustCompile to inject options/loggin and changing the arity; passing regexp.Compile (which returns (*Regexp, error) - two outputs) instead of regexp.MustCompile; using a named string type as the parameter.

Related errors


AI-assisted analysis of gofiber/fiber@9a4c7e57fe (2026-08-04). Data as JSON: /data/errors/57621590492a80e5.json. Report an issue: GitHub.