gofr-dev/gofr · error

invalid array index

Error message

invalid array index

What it means

errInvalidArrayIndex is a sentinel error in the GoFr RBAC middleware's claim-path parser. When JWTClaimPath uses array notation like "roles[abc]", extractArrayClaim parses the text between the brackets with fmt.Sscanf("%d"); if the segment is not a valid non-negative integer, this error is returned. It signals a configuration/claim-path syntax problem, not a problem with the token itself.

Source

Thrown at pkg/gofr/rbac/middleware.go:62

	ErrAccessDenied = errors.New("forbidden: access denied")

	// ErrRoleNotFound is returned when role cannot be extracted from request.
	ErrRoleNotFound = errors.New("unauthorized: role not found")

	// errJWTClaimsNotFound is returned when JWT claims are not found in request context.
	errJWTClaimsNotFound = errors.New("JWT claims not found in request context")

	// errEmptyClaimPath is returned when claim path is empty.
	errEmptyClaimPath = errors.New("empty claim path")

	// errClaimPathNotFound is returned when a claim path is not found in JWT claims.
	errClaimPathNotFound = errors.New("claim path not found")

	// errInvalidArrayNotation is returned when array notation is invalid.
	errInvalidArrayNotation = errors.New("invalid array notation")

	// errInvalidArrayIndex is returned when array index is invalid.
	errInvalidArrayIndex = errors.New("invalid array index")

	// errClaimKeyNotFound is returned when a claim key is not found.
	errClaimKeyNotFound = errors.New("claim key not found")

	// errClaimValueNotArray is returned when a claim value is not an array.
	errClaimValueNotArray = errors.New("claim value is not an array")

	// errArrayIndexOutOfBounds is returned when array index is out of bounds.
	errArrayIndexOutOfBounds = errors.New("array index out of bounds")

	// errInvalidClaimStructure is returned when claim structure is invalid.
	errInvalidClaimStructure = errors.New("invalid claim structure")

	// errAuthorizationError is returned as a generic error message for unknown errors in traces.
	errAuthorizationError = errors.New("authorization error")
)

// Middleware creates an HTTP middleware function that enforces RBAC authorization.

View on GitHub (pinned to 187eb24962)

Solutions

  1. Fix JWTClaimPath so the bracket contains a plain non-negative integer, e.g. "roles[0]" instead of "roles[first]".
  2. If you need the first element regardless of length, use index 0 explicitly; negative indexes are rejected.
  3. Validate claim-path syntax at startup with a small parse check before wiring the middleware.
  4. If the claim is not actually an array, drop the bracket notation and use a plain key or dot notation path.

Example fix

// before
config.JWTClaimPath = "roles[first]"
// after
config.JWTClaimPath = "roles[0]"
Defensive patterns

Strategy: validation

Validate before calling

var claimPathRe = regexp.MustCompile(`^[A-Za-z0-9_.]+(\[[0-9]+\])*$`)
func validClaimPath(p string) bool { return p != "" && claimPathRe.MatchString(p) }
// call at startup: if !validClaimPath(cfg.JWTClaimPath) { log.Fatal("invalid JWTClaimPath") }

Type guard

func hasValidArrayIndex(path string) bool {
    i := strings.Index(path, "[")
    if i < 0 || !strings.HasSuffix(path, "]") { return true }
    idx := path[i+1 : len(path)-1]
    n, err := strconv.Atoi(idx)
    return err == nil && n >= 0
}

Try / catch

role, err := extractRole(r, cfg)
if err != nil {
    if strings.Contains(err.Error(), "invalid array index") {
        logger.Error("bad JWTClaimPath syntax; check config", "err", err)
    }
    http.Error(w, "unauthorized", http.StatusUnauthorized)
    return
}

Prevention

When it happens

Trigger: Configuring Config.JWTClaimPath with array notation whose bracket contents are non-numeric or negative, e.g. "roles[first]", "roles[-1]", "roles[]", or "roles[0a]"; extractClaimValue sees a '[' and dispatches to extractArrayClaim, where Sscanf fails and errInvalidArrayIndex is wrapped in the returned error.

Common situations: Typo in the claim path in service config or environment variables; copying a path like "roles[*]" from documentation; templated config where the index placeholder was not substituted ("roles[${IDX}]"); hand-written paths assuming string keys inside brackets work.

Related errors


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