{"record":{"id":"641ce1293415d8c6","repo":"gofr-dev/gofr","slug":"w-s","errorCode":null,"errorMessage":"%w: %s","messagePattern":"%w: %s","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/gofr/datasource/elasticsearch/documents.go","lineNumber":170,"sourceCode":"\n\tstart := time.Now()\n\n\ttracedCtx, span := c.addTrace(ctx, \"delete-document\", []string{index}, id)\n\n\treq := esapi.DeleteRequest{\n\t\tIndex:      index,\n\t\tDocumentID: id,\n\t}\n\n\tres, err := req.Do(tracedCtx, c.client)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"%w: deleting document: %w\", errOperation, err)\n\t}\n\n\tdefer res.Body.Close()\n\n\tif res.IsError() {\n\t\treturn fmt.Errorf(\"%w: %s\", errResponse, res.String())\n\t}\n\n\tc.sendOperationStats(start, fmt.Sprintf(\"DELETE DOCUMENT %s/%s\", index, id),\n\t\t[]string{index}, id, nil, span)\n\n\treturn nil\n}\n","sourceCodeStart":152,"sourceCodeEnd":178,"githubUrl":"https://github.com/gofr-dev/gofr/blob/187eb24962502e91f1fee856230670958b66e89c/pkg/gofr/datasource/elasticsearch/documents.go#L152-L178","documentation":"For a simple (non-array, non-dotted) path, extractClaimValue does a direct map lookup claims[path]. If the key is absent it wraps errClaimPathNotFound with the requested path. This means the token parsed fine, but the claim key configured for role extraction does not exist in the token.","triggerScenarios":"Configured claim path (e.g. \"role\") not present in the incoming JWT's payload — issuer puts the role under a different key (\"roles\", \"https://myapp.com/roles\", \"authorities\") or omits it entirely for tokens issued by a different flow (password reset, service accounts).","commonSituations":"Migrating identity providers (Auth0 namespaced claims vs custom server claims); tokens minted by a test fixture without a role claim; keycloak realm vs client roles mapping; typo in the configured claim name.","solutions":["Print/decode the actual JWT payload and align the configured claim path with the real key name","Ensure the auth server always includes the role claim in access tokens (audience/mapper/protocol-mapper config)","Handle the wrapped error with errors.Is(err, errClaimPathNotFound) and treat as 401/403 with a clear log of the missing path"],"exampleFix":"// before\nv, err := extractClaimValue(claims, \"role\")\n// after\nv, err := extractClaimValue(claims, \"https://myapp.example.com/roles\") // matches actual issuer claim key","handlingStrategy":"try-catch","validationCode":"// decode token payload first and confirm the key exists\nclaims := jwt.MapClaims{}\njwt.ParseWithClaims(token, &claims, keyfunc)\nif _, ok := claims[\"role\"]; !ok {\n    // reject or choose correct claim name before calling middleware\n}","typeGuard":"func hasClaim(claims jwt.MapClaims, key string) bool {\n    _, ok := claims[key]\n    return ok\n}","tryCatchPattern":"v, err := extractClaimValue(claims, path)\nif errors.Is(err, errClaimPathNotFound) {\n    http.Error(w, \"missing role claim: \"+path, http.StatusUnauthorized)\n    return\n}","preventionTips":["Match the configured claim name against a real decoded token from your IdP (jwt.io) before deploying","Document the required claim in your auth-server mapper/protocol-mapper config","Add an integration test with a fixture token that includes the claim","Handle issuer variants (namespaced claims) with a list of candidate paths"],"tags":["jwt","rbac","claims"],"backgroundTag":"jwt-claim-not-found","analyzedSha":"187eb24962502e91f1fee856230670958b66e89c","analyzedAt":"2026-09-01T20:34:54.554Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}