gofr-dev/gofr · error

endpoint[%d]: %w: %s. Example: /api/users/{id:[0-9]+}

Error message

endpoint[%d]: %w: %s. Example: /api/users/{id:[0-9]+}

What it means

checkRegexIndicators found regex escapes (\\d, \\w, \\s) in the path outside any mux variable constraint. Bare regex escapes in paths are unsupported; move them inside a {var:constraint} expression or remove them.

Source

Thrown at pkg/gofr/rbac/config.go:254

	return nil
}

// checkRegexPattern checks if path contains old regex pattern.
func (*Config) checkRegexPattern(path string, index int) error {
	if strings.HasPrefix(path, "^") || strings.HasSuffix(path, "$") {
		return fmt.Errorf("endpoint[%d]: %w: %s. Example: /api/users/{id:[0-9]+} instead of ^/api/users/\\d+$",
			index, errRegexPatternNotSupported, path)
	}

	return nil
}

// checkRegexIndicators checks if path contains regex indicators outside variable constraints.
func (*Config) checkRegexIndicators(path string, index int) error {
	if strings.Contains(path, "\\d") || strings.Contains(path, "\\w") || strings.Contains(path, "\\s") {
		// Only allow if it's inside a variable constraint like {id:[0-9]+}
		if !strings.Contains(path, "{") || !strings.Contains(path, ":") {
			return fmt.Errorf("endpoint[%d]: %w: %s. Example: /api/users/{id:[0-9]+}",
				index, errRegexIndicatorNotSupported, path)
		}
	}

	return nil
}

// processUnifiedConfig processes the unified Roles and Endpoints config
// and builds internal maps for efficient lookup.
// Config is read-only after initialization, so no mutex is needed.
func (c *Config) processUnifiedConfig() error {
	c.initializeMaps()
	c.buildRolePermissionsMap()

	return c.buildEndpointPermissionMap()
}

// initializeMaps initializes internal maps.

View on GitHub (pinned to 187eb24962)

Solutions

  1. Wrap the regex segment in a named variable with constraint: /api/users/{id:[0-9]+}.
  2. Or remove the escape and use a plain segment or {resource} if no regex is needed.
  3. Search the config for \\d, \\w, \\s and fix each occurrence.

Example fix

// before
path: "/api/users/\\d+"
// after
path: "/api/users/{id:[0-9]+}"
Defensive patterns

Strategy: validation

Validate before calling

func bareRegexEscape(p string) bool {
    for _, esc := range []string{"\\d", "\\w", "\\s"} {
        if strings.Contains(p, esc) && !(strings.Contains(p, "{") && strings.Contains(p, ":")) {
            return true
        }
    }
    return false
}
for i, ep := range endpoints {
    if bareRegexEscape(ep.Path) {
        return fmt.Errorf("endpoint[%d] %s: move regex escapes into a constraint like {id:[0-9]+}", i, ep.Path)
    }
}

Try / catch

if err := prevalidateRegexIndicators(endpoints); err != nil { return err }
if _, err := rbac.LoadPermissions(path, logger, metrics, tracer); err != nil {
    if strings.Contains(err.Error(), "Example: /api/users/{id:[0-9]+}") {
        return fmt.Errorf("wrap regex escapes in variable constraints: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: An endpoint path like /api/users/\\d+ (no braces/colon present) passed to EnableRBAC/LoadPermissions via validate -> validateEndpointPath -> checkRegexIndicators.

Common situations: Partial migration from regex routes where anchors were removed but escapes remained; hand-written numeric-segment paths; copy-paste from regex route tables.

Related errors


AI-assisted analysis of gofr-dev/gofr@187eb24962 (2026-09-01). Data as JSON: /api/errors/84a21a7475722620. Report an issue: GitHub.