gofiber/fiber · error

betweenLen constraint requires two arguments

Error message

betweenLen constraint requires two arguments

What it means

The betweenLen route-parameter constraint requires that the length of a matched path segment fall within an inclusive [lo, hi] range. It is declared inline in a route pattern as :param<betweenLen(lo,hi)>. Its Analyze method (part of the public ConstraintAnalyzer interface, constraint.go:84-87) needs exactly two integer arguments; with fewer than two it returns this error. Note that fiber's built-in registration path (newConstraint at constraint.go:188) currently swallows Analyze errors, so this surfaces when callers invoke Analyze directly or via a custom-constraint wrapper that delegates to it (constraint.go:105).

Solutions

  1. Provide two integer arguments: :param<betweenLen(2,10)>.
  2. If only one bound is needed, switch to :param<minLen(n)> or :param<maxLen(n)> instead.
  3. Ensure the comma is not escaped (an escaped comma \, becomes part of a single argument).
  4. Add a startup unit test that drives a request through App.Test to confirm the constraint behaves as intended.

Example fix

// before
app.Get("/u/:name<betweenLen(3)>", h)
// after
app.Get("/u/:name<betweenLen(3,20)>", h)
Defensive patterns

Strategy: validation

Validate before calling

// Unit-test every route pattern at startup. The built-in registration path
// silently swallows Analyze errors, so drive a representative request instead.
func TestRoutePatterns(t *testing.T) {
    cases := []struct{ path, param string }{
        {"/u/:name<betweenLen(3,20)>", "abc"},
    }
    for _, tc := range cases {
        app := fiber.New()
        app.Get(tc.path, func(c fiber.Ctx) error { return c.SendString("ok") })
        req := httptest.NewRequest("GET", strings.Replace(tc.path, ":name", tc.param, 1), nil)
        resp, _ := app.Test(req)
        if resp.StatusCode != 200 {
            t.Fatalf("pattern %s rejected valid param", tc.path)
        }
    }
}

Try / catch

// When calling Analyze directly on a ConstraintAnalyzer (e.g. inside a custom
// constraint that delegates), propagate the error rather than ignoring it.
typed, err := analyzer.Analyze(args)
if err != nil {
    return nil, fmt.Errorf("init route constraint: %w", err)
}

Prevention

When it happens

Trigger: Calling Analyze on a betweenLen constraint with fewer than two comma-separated arguments. This happens when a route pattern is written as :name<betweenLen(5)> (one arg), :name<betweenLen()> (empty), :name<betweenLen> (no parens), or :name<betweenLen(2\,10)> (escaped comma collapses two args into one). Also returned when a custom constraint's Analyze delegates to betweenLenConstraintType through the customConstraintWrapper.

Common situations: Typos in route definitions; copy-paste from minLen/maxLen forgetting the second bound; escaping the comma separator inside the args list; migrating from a single-bound length constraint to a ranged one.

Related errors


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

Appendix: source

Thrown at constraint.go:415

func (lenConstraintType) Execute(param string, data []any) bool {
	if len(data) == 0 {
		return false
	}
	limit, ok := data[0].(int)
	if !ok {
		return false
	}
	return len(param) == limit
}

type betweenLenConstraintType struct{}

func (betweenLenConstraintType) Name() string { return ConstraintBetweenLen }
func (betweenLenConstraintType) Analyze(args []string) ([]any, error) {
	args = parseConstraintArgs(args)
	if len(args) < 2 {
		return nil, errors.New("betweenLen constraint requires two arguments")
	}
	lo, err := strconv.Atoi(args[0])
	if err != nil {
		return nil, fmt.Errorf("parse constraint arg: %w", err)
	}
	hi, err := strconv.Atoi(args[1])
	if err != nil {
		return nil, fmt.Errorf("parse constraint arg: %w", err)
	}
	return []any{lo, hi}, nil
}

func (betweenLenConstraintType) Execute(param string, data []any) bool {
	if len(data) < 2 {
		return false
	}
	lo, ok := data[0].(int)
	if !ok {

View on GitHub (pinned to a105acad6c)