gofiber/fiber · critical

fiber: Config.RegexHandler must not return nil

Error message

fiber: Config.RegexHandler must not return nil

What it means

After compileRegex invokes the RegexHandler, isNilRegexMatcher checks the returned matcher; if it is a nil interface or a nil pointer/slice/map/etc., the app panics. A nil matcher would crash on the first request, so registration fails fast instead.

Solutions

  1. Have your RegexHandler propagate compile errors (panic or return a non-nil fallback) instead of returning nil.
  2. Default to regexp.MustCompile when in doubt: leave Config.RegexHandler unset.
  3. In a custom handler, on Compile error, fall back to a never-match sentinel: regexp.MustCompile(`$^`).

Example fix

// before
RegexHandler: func(p string) *regexp.Regexp {
  re, err := regexp.Compile(p)
  if err != nil { return nil } // triggers this panic
  return re
}

// after
RegexHandler: func(p string) *regexp.Regexp {
  re, err := regexp.Compile(p)
  if err != nil { return regexp.MustCompile(`\A\z`) } // matches nothing, but non-nil
  return re
}
Defensive patterns

Strategy: validation

Validate before calling

// Smoke-test the handler against a sample pattern before registering
func checkRegexHandlerNonNil(h func(string) any) error {
    out := h("test")
    if out == nil { return errors.New("handler returned nil") }
    rv := reflect.ValueOf(out)
    if (rv.Kind() == reflect.Ptr || rv.Kind() == reflect.Interface) && rv.IsNil() {
        return errors.New("handler returned typed nil")
    }
    return nil
}

Prevention

When it happens

Trigger: Config.RegexHandler returns nil, or returns a typed nil (e.g. (*regexp.Regexp)(nil)) that compiles a pattern that the handler then returns as nil on failure.

Common situations: Custom handler that swallows compile errors and returns nil; handler that returns a nil *regexp.Regexp when regexp.Compile fails instead of propagating the error; refactor returning zero value.

Related errors


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

Appendix: source

Thrown at constraint.go:46

		return true
	}
	matcherValue := reflect.ValueOf(matcher)
	switch matcherValue.Kind() {
	case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Pointer, reflect.Slice:
		return matcherValue.IsNil()
	default:
		return false
	}
}

func compileRegex(handler any, pattern string) regexMatcher {
	result := reflect.ValueOf(handler).Call([]reflect.Value{reflect.ValueOf(pattern)})
	matcher, ok := result[0].Interface().(regexMatcher)
	if !ok {
		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")

View on GitHub (pinned to a105acad6c)