{"record":{"id":"88f396fd0f0dafe1","repo":"gofr-dev/gofr","slug":"invalid-array-index","errorCode":null,"errorMessage":"invalid array index","messagePattern":"invalid array index","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/gofr/rbac/middleware.go","lineNumber":62,"sourceCode":"\tErrAccessDenied = errors.New(\"forbidden: access denied\")\n\n\t// ErrRoleNotFound is returned when role cannot be extracted from request.\n\tErrRoleNotFound = errors.New(\"unauthorized: role not found\")\n\n\t// errJWTClaimsNotFound is returned when JWT claims are not found in request context.\n\terrJWTClaimsNotFound = errors.New(\"JWT claims not found in request context\")\n\n\t// errEmptyClaimPath is returned when claim path is empty.\n\terrEmptyClaimPath = errors.New(\"empty claim path\")\n\n\t// errClaimPathNotFound is returned when a claim path is not found in JWT claims.\n\terrClaimPathNotFound = errors.New(\"claim path not found\")\n\n\t// errInvalidArrayNotation is returned when array notation is invalid.\n\terrInvalidArrayNotation = errors.New(\"invalid array notation\")\n\n\t// errInvalidArrayIndex is returned when array index is invalid.\n\terrInvalidArrayIndex = errors.New(\"invalid array index\")\n\n\t// errClaimKeyNotFound is returned when a claim key is not found.\n\terrClaimKeyNotFound = errors.New(\"claim key not found\")\n\n\t// errClaimValueNotArray is returned when a claim value is not an array.\n\terrClaimValueNotArray = errors.New(\"claim value is not an array\")\n\n\t// errArrayIndexOutOfBounds is returned when array index is out of bounds.\n\terrArrayIndexOutOfBounds = errors.New(\"array index out of bounds\")\n\n\t// errInvalidClaimStructure is returned when claim structure is invalid.\n\terrInvalidClaimStructure = errors.New(\"invalid claim structure\")\n\n\t// errAuthorizationError is returned as a generic error message for unknown errors in traces.\n\terrAuthorizationError = errors.New(\"authorization error\")\n)\n\n// Middleware creates an HTTP middleware function that enforces RBAC authorization.","sourceCodeStart":44,"sourceCodeEnd":80,"githubUrl":"https://github.com/gofr-dev/gofr/blob/187eb24962502e91f1fee856230670958b66e89c/pkg/gofr/rbac/middleware.go#L44-L80","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Fix JWTClaimPath so the bracket contains a plain non-negative integer, e.g. \"roles[0]\" instead of \"roles[first]\".","If you need the first element regardless of length, use index 0 explicitly; negative indexes are rejected.","Validate claim-path syntax at startup with a small parse check before wiring the middleware.","If the claim is not actually an array, drop the bracket notation and use a plain key or dot notation path."],"exampleFix":"// before\nconfig.JWTClaimPath = \"roles[first]\"\n// after\nconfig.JWTClaimPath = \"roles[0]\"","handlingStrategy":"validation","validationCode":"var claimPathRe = regexp.MustCompile(`^[A-Za-z0-9_.]+(\\[[0-9]+\\])*$`)\nfunc validClaimPath(p string) bool { return p != \"\" && claimPathRe.MatchString(p) }\n// call at startup: if !validClaimPath(cfg.JWTClaimPath) { log.Fatal(\"invalid JWTClaimPath\") }","typeGuard":"func hasValidArrayIndex(path string) bool {\n    i := strings.Index(path, \"[\")\n    if i < 0 || !strings.HasSuffix(path, \"]\") { return true }\n    idx := path[i+1 : len(path)-1]\n    n, err := strconv.Atoi(idx)\n    return err == nil && n >= 0\n}","tryCatchPattern":"role, err := extractRole(r, cfg)\nif err != nil {\n    if strings.Contains(err.Error(), \"invalid array index\") {\n        logger.Error(\"bad JWTClaimPath syntax; check config\", \"err\", err)\n    }\n    http.Error(w, \"unauthorized\", http.StatusUnauthorized)\n    return\n}","preventionTips":["Validate JWTClaimPath format with a regex at service startup","Keep claim paths in typed config with unit-tested example values","Never template indexes into claim paths without substituting them"],"tags":["go","jwt","rbac","configuration"],"backgroundTag":"jwt-claim-path-invalid","analyzedSha":"187eb24962502e91f1fee856230670958b66e89c","analyzedAt":"2026-09-01T20:34:54.554Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}