gofr-dev/gofr · error

endpoint[%d]: %w: %s

Error message

endpoint[%d]: %w: %s

What it means

Config.validate found a non-public endpoint (index %d) whose RequiredPermissions list is empty, wrapped with ErrEndpointMissingPermissions. RBAC refuses to load because a protected endpoint without required permissions would silently allow everyone.

Source

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

	if err := config.validate(); err != nil {
		return nil, fmt.Errorf("invalid RBAC config: %w", err)
	}

	// Process unified config to build internal maps
	if err := config.processUnifiedConfig(); err != nil {
		return nil, fmt.Errorf("failed to process unified config: %w", err)
	}

	return &config, nil
}

// validate validates the RBAC configuration.
func (c *Config) validate() error {
	// Validate endpoints: non-public endpoints must have RequiredPermissions
	// Also validate that paths use mux patterns only (no wildcards or old regex)
	for i, endpoint := range c.Endpoints {
		if !endpoint.Public && len(endpoint.RequiredPermissions) == 0 {
			return fmt.Errorf("endpoint[%d]: %w: %s", i, ErrEndpointMissingPermissions, endpoint.Path)
		}

		// Validate path pattern
		if err := c.validateEndpointPath(endpoint.Path, i); err != nil {
			return err
		}
	}

	return nil
}

// validateEndpointPath validates that an endpoint path uses mux patterns only.
// Rejects wildcard patterns (/*) and old regex patterns (^...$).
func (c *Config) validateEndpointPath(path string, index int) error {
	if path == "" {
		return nil // Empty path is handled elsewhere
	}

View on GitHub (pinned to 187eb24962)

Solutions

  1. Add at least one required permission to the endpoint named in the error.
  2. If the endpoint should be public, explicitly set Public=true.
  3. If permissions are injected via templates, verify the rendered config is non-empty.

Example fix

// before
rbac.Endpoint{Path: "/api/users", Methods: []string{"GET"}}
// after
rbac.Endpoint{Path: "/api/users", Methods: []string{"GET"}, RequiredPermissions: []string{"users:read"}}
Defensive patterns

Strategy: validation

Validate before calling

for i, ep := range endpoints {
    if !ep.Public && len(ep.RequiredPermissions) == 0 {
        return fmt.Errorf("endpoint[%d] (%s): must set RequiredPermissions or Public=true", i, ep.Path)
    }
}

Try / catch

if err := prevalidateEndpoints(endpoints); err != nil { return err }
if _, err := rbac.LoadPermissions(path, logger, metrics, tracer); err != nil {
    var target error
    if errors.Is(err, rbac.ErrEndpointMissingPermissions) || strings.Contains(err.Error(), "endpoint[") {
        return fmt.Errorf("rbac config rejected: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: An Endpoints entry with Public=false and len(RequiredPermissions)==0 passed to EnableRBAC/LoadPermissions.

Common situations: Adding a protected route and forgetting requiredPermissions; an empty array after filtering/templating removed values; migrating a public endpoint to protected without adding permissions.

Related errors


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