{"record":{"id":"8e3fd9f355b2dd75","repo":"ory/hydra","slug":"gettokenclaims-must-not-be-nil","errorCode":null,"errorMessage":"GetTokenClaims() must not be nil","messagePattern":"GetTokenClaims\\(\\) must not be nil","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"fosite/handler/oauth2/strategy_jwt.go","lineNumber":92,"sourceCode":"\tcase v.Has(jwt.ValidationErrorExpired):\n\t\treturn fosite.ErrTokenExpired\n\tcase v.Has(jwt.ValidationErrorAudience |\n\t\tjwt.ValidationErrorIssuedAt |\n\t\tjwt.ValidationErrorIssuer |\n\t\tjwt.ValidationErrorNotValidYet |\n\t\tjwt.ValidationErrorId |\n\t\tjwt.ValidationErrorClaimsInvalid):\n\t\treturn fosite.ErrTokenClaim\n\tdefault:\n\t\treturn fosite.ErrRequestUnauthorized\n\t}\n}\n\nfunc (h *DefaultJWTStrategy) generate(ctx context.Context, tokenType fosite.TokenType, requester fosite.Requester) (string, string, error) {\n\tif jwtSession, ok := requester.GetSession().(JWTSessionContainer); !ok {\n\t\treturn \"\", \"\", errors.Errorf(\"Session must be of type JWTSessionContainer but got type: %T\", requester.GetSession())\n\t} else if claims := jwtSession.GetJWTClaims(); claims == nil {\n\t\treturn \"\", \"\", errors.New(\"GetTokenClaims() must not be nil\")\n\t} else {\n\t\tclaims.\n\t\t\tWith(\n\t\t\t\tjwtSession.GetExpiresAt(tokenType),\n\t\t\t\trequester.GetGrantedScopes(),\n\t\t\t\trequester.GetGrantedAudience(),\n\t\t\t).\n\t\t\tWithDefaults(\n\t\t\t\ttime.Now().UTC(),\n\t\t\t\th.Config.GetAccessTokenIssuer(ctx),\n\t\t\t).\n\t\t\tWithScopeField(\n\t\t\t\th.Config.GetJWTScopeField(ctx),\n\t\t\t)\n\n\t\treturn h.Signer.Generate(ctx, claims.ToMapClaims(), jwtSession.GetJWTHeader())\n\t}\n}","sourceCodeStart":74,"sourceCodeEnd":110,"githubUrl":"https://github.com/ory/hydra/blob/4174065ffb052799890f7480f5360a877a67ffc1/fosite/handler/oauth2/strategy_jwt.go#L74-L110","documentation":"After a successful JWTSessionContainer assertion, generate() calls GetJWTClaims() and refuses to proceed if it returns nil. A JWT session without a claims object cannot produce a valid token payload, so fosite fails fast with this error.","triggerScenarios":"Calling GenerateAccessToken with a session whose GetJWTClaims() returns nil — e.g. a JWTSessionContainer implementation that never initialized its claims field, or a session deserialized from storage with claims lost.","commonSituations":"Custom JWTSessionContainer implementations that lazily allocate claims but were constructed without them; copying session structs so the pointer to claims was nil; sessions restored from JSON where claims were omitted.","solutions":["Initialize the claims object in your session constructor: sess.GetJWTClaims().With(...) or ensure GetJWTClaims() always returns a non-nil *jwt.JWTClaims","Fix custom GetJWTClaims() to lazily create the claims struct if nil instead of returning nil","Verify serialization/deserialization of sessions preserves the claims object","Check that storage round-trips (cache, DB) don't strip claims from the session"],"exampleFix":"// before\nfunc (s *MySession) GetJWTClaims() jwt.JWTClaimsContainer { return s.claims } // nil if unset\n// after\nfunc (s *MySession) GetJWTClaims() jwt.JWTClaimsContainer {\n    if s.claims == nil { s.claims = &jwt.JWTClaims{} }\n    return s.claims\n}","handlingStrategy":"type-guard","validationCode":"if js, ok := req.GetSession().(JWTSessionContainer); ok && js.GetJWTClaims() == nil {\n    return errors.New(\"session has nil JWT claims; initialize claims before token generation\")\n}","typeGuard":"func hasJWTClaims(s fosite.Session) bool {\n    js, ok := s.(JWTSessionContainer)\n    return ok && js.GetJWTClaims() != nil\n}","tryCatchPattern":"resp, err := oauth2Client.GetAccessToken(ctx, req)\nif err != nil && strings.Contains(err.Error(), \"GetTokenClaims() must not be nil\") {\n    log.Fatalf(\"session misconfigured: claims were nil: %v\", err)\n}","preventionTips":["Initialize claims in your session constructor, never leave the claims field zero-valued","Make GetJWTClaims() lazily allocate a non-nil claims object","Include claims in session serialization (storage/cache round-trips)","Add a unit test that generates a token from a freshly constructed session"],"tags":["oauth2","fosite","jwt","nil-claims","session"],"backgroundTag":"jwt-claims-nil","analyzedSha":"4174065ffb052799890f7480f5360a877a67ffc1","analyzedAt":"2026-09-03T14:52:41.581Z","contentChangedAt":"2026-09-03T14:52:41.581Z","schemaVersion":2},"datasetVersion":"2026-09-10T17:17:09.494Z"}