{"record":{"id":"076cb934a186042c","repo":"ory/hydra","slug":"failed-to-set-token-lifespans-due-to-failed-client","errorCode":null,"errorMessage":"failed to set token lifespans due to failed client type assertion","messagePattern":"failed to set token lifespans due to failed client type assertion","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"fosite/storage/memory.go","lineNumber":263,"sourceCode":"\tdefer s.clientsMutex.RUnlock()\n\n\tcl, ok := s.Clients[id]\n\tif !ok {\n\t\treturn nil, fosite.ErrNotFound\n\t}\n\treturn cl, nil\n}\n\nfunc (s *MemoryStore) SetTokenLifespans(clientID string, lifespans *fosite.ClientLifespanConfig) error {\n\ts.clientsMutex.RLock()\n\tdefer s.clientsMutex.RUnlock()\n\n\tif client, ok := s.Clients[clientID]; ok {\n\t\tif clc, ok := client.(*fosite.DefaultClientWithCustomTokenLifespans); ok {\n\t\t\tclc.SetTokenLifespans(lifespans)\n\t\t\treturn nil\n\t\t}\n\t\treturn fosite.ErrorToRFC6749Error(errors.New(\"failed to set token lifespans due to failed client type assertion\"))\n\t}\n\treturn fosite.ErrNotFound\n}\n\nfunc (s *MemoryStore) ClientAssertionJWTValid(_ context.Context, jti string) error {\n\ts.blacklistedJTIsMutex.RLock()\n\tdefer s.blacklistedJTIsMutex.RUnlock()\n\n\tif exp, exists := s.BlacklistedJTIs[jti]; exists && exp.After(time.Now()) {\n\t\treturn fosite.ErrJTIKnown\n\t}\n\n\treturn nil\n}\n\nfunc (s *MemoryStore) SetClientAssertionJWT(_ context.Context, jti string, exp time.Time) error {\n\ts.blacklistedJTIsMutex.Lock()\n\tdefer s.blacklistedJTIsMutex.Unlock()","sourceCodeStart":245,"sourceCodeEnd":281,"githubUrl":"https://github.com/ory/hydra/blob/4174065ffb052799890f7480f5360a877a67ffc1/fosite/storage/memory.go#L245-L281","documentation":"MemoryStore.SetTokenLifespans only supports clients stored as *fosite.DefaultClientWithCustomTokenLifespans. If a client with the given ID exists but is a different concrete type in the store's map, it returns an RFC6749 error about the failed type assertion instead of applying the lifespans.","triggerScenarios":"Calling SetTokenLifespans(ctx, clientID, lifespans) on a MemoryStore where s.Clients[clientID] was registered as a *fosite.DefaultClient (or any type other than *fosite.DefaultClientWithCustomTokenLifespans).","commonSituations":"Tests or in-memory setups seeding clients with the plain DefaultClient type but later trying to set custom token lifespans; migration from an older client type that lacks the TokenLifespans support embedded struct.","solutions":["Store clients as *fosite.DefaultClientWithCustomTokenLifespans (which embeds TokenLifespans) when seeding the MemoryStore","Replace the existing client entry with the correct type before calling SetTokenLifespans","If the client type cannot change, skip SetTokenLifespans and configure lifespans on the client at registration time"],"exampleFix":"// before\nstore.Clients[clientID] = &fosite.DefaultClient{ID: clientID}\nstore.SetTokenLifespans(ctx, clientID, lifespans)\n// after\nstore.Clients[clientID] = &fosite.DefaultClientWithCustomTokenLifespans{\n    DefaultClient: &fosite.DefaultClient{ID: clientID},\n}\nstore.SetTokenLifespans(ctx, clientID, lifespans)","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"func canSetLifespans(client fosite.Client) bool {\n    _, ok := client.(*fosite.DefaultClientWithCustomTokenLifespans)\n    return ok\n}","tryCatchPattern":"if err := store.SetTokenLifespans(ctx, clientID, lifespans); err != nil {\n    var rfcErr *fosite.RFC6749Error\n    if errors.As(err, &rfcErr) {\n        // re-register the client with the correct type, then retry\n    }\n}","preventionTips":["Always seed MemoryStore clients as *fosite.DefaultClientWithCustomTokenLifespans","Assert client type at registration time instead of lifespan-set time","Keep client construction in one factory function"],"tags":["fosite","oauth2","type-assertion","storage"],"backgroundTag":"type-assertion-failed","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"}