gofr-dev/gofr · error

invalid RBAC config: %w

Error message

invalid RBAC config: %w

What it means

After parsing, LoadPermissions runs Config.validate() and the config was semantically invalid (e.g. a non-public endpoint has no RequiredPermissions, or a path pattern is malformed). The underlying validation error is wrapped, so read the full chained message.

Source

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

		if err := json.Unmarshal(data, &config); err != nil {
			return nil, fmt.Errorf("failed to parse JSON config file %s: %w", path, err)
		}
	default:
		return nil, fmt.Errorf("unsupported config file format: %s (supported: .json, .yaml, .yml): %w", ext, errUnsupportedFormat)
	}

	// Set dependencies
	config.Logger = logger
	config.Metrics = metrics
	config.Tracer = tracer

	// Initialize mux router for pattern matching
	// Use StrictSlash(false) to match the application router's behavior
	config.muxRouter = mux.NewRouter().StrictSlash(false)

	// Validate config before processing
	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)
		}

View on GitHub (pinned to 187eb24962)

Solutions

  1. Read the wrapped cause to see which endpoint index/field failed.
  2. Add a non-empty requiredPermissions list to every non-public endpoint.
  3. Set public: true only for endpoints genuinely meant to be unauthenticated.
  4. Fix the path pattern to use mux syntax (see errors 375-379 for pattern specifics).

Example fix

// before
{ "path": "/api/orders", "requiredPermissions": [] }
// after
{ "path": "/api/orders", "requiredPermissions": ["orders:read"] }
Defensive patterns

Strategy: validation

Validate before calling

for i, ep := range cfg.Endpoints {
    if !ep.Public && len(ep.RequiredPermissions) == 0 {
        return fmt.Errorf("endpoint[%d] %s: non-public endpoint needs requiredPermissions", i, ep.Path)
    }
}

Try / catch

if err := cfg.validateShape(); err != nil { return err }
if _, err := rbac.LoadPermissions(path, logger, metrics, tracer); err != nil {
    if strings.Contains(err.Error(), "invalid RBAC config") {
        return fmt.Errorf("fix rbac config: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: EnableRBAC/LoadPermissions with an Endpoints entry where Public is false and RequiredPermissions is empty, or where the path fails validateEndpointPath (bad mux pattern, wildcard, regex style).

Common situations: Adding a new protected route and forgetting requiredPermissions; a refactoring dropped the permissions array; copy-pasting a path pattern from a non-mux router.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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