{"record":{"id":"1fba0994cb9f1f60","repo":"gofiber/fiber","slug":"limiter-unexpected-entry-type-t-for-key-q","errorCode":null,"errorMessage":"limiter: unexpected entry type %T for key %q","messagePattern":"limiter: unexpected entry type %T for key %q","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"middleware/limiter/manager.go","lineNumber":90,"sourceCode":"\t\tif raw != nil {\n\t\t\tit := m.acquire()\n\t\t\tif _, err := it.UnmarshalMsg(raw); err != nil {\n\t\t\t\tm.release(it)\n\t\t\t\treturn nil, fmt.Errorf(\"limiter: failed to unmarshal key %q: %w\", m.logKey(key), err)\n\t\t\t}\n\t\t\treturn it, nil\n\t\t}\n\t\treturn m.acquire(), nil\n\t}\n\n\tvalue := m.memory.Get(key)\n\tif value == nil {\n\t\treturn m.acquire(), nil\n\t}\n\n\tit, ok := value.(*item)\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"limiter: unexpected entry type %T for key %q\", value, m.logKey(key))\n\t}\n\n\treturn it, nil\n}\n\n// set data to storage or memory\nfunc (m *manager) set(ctx context.Context, key string, it *item, exp time.Duration) error {\n\tif m.storage != nil {\n\t\traw, err := it.MarshalMsg(nil)\n\t\tif err != nil {\n\t\t\tm.release(it)\n\t\t\treturn fmt.Errorf(\"limiter: failed to marshal key %q: %w\", m.logKey(key), err)\n\t\t}\n\t\tif err := m.storage.SetWithContext(ctx, key, raw, exp); err != nil {\n\t\t\tm.release(it)\n\t\t\treturn fmt.Errorf(\"limiter: failed to store key %q: %w\", m.logKey(key), err)\n\t\t}\n\t\tm.release(it)","sourceCodeStart":72,"sourceCodeEnd":108,"githubUrl":"https://github.com/gofiber/fiber/blob/a105acad6c1e4576a77f01e02973f67e962bb58d/middleware/limiter/manager.go#L72-L108","documentation":"On the in-memory storage path (no fiber.Storage configured), the manager stores *item values in memory.Storage. A type assertion to *item failing means something else was Put under the same key. Under normal use this is unreachable because only the manager writes to its memory store.","triggerScenarios":"External code obtained a reference to the same memory.Storage instance and Set a non-*item value under a key that collides with the limiter's key prefix; an in-process test fixture populated the memory store with the wrong type; a second limiter manager sharing the same memory.Storage with a different value type.","commonSituations":"Test setup that reuses a shared memory.Storage across middleware; a fork or plugin that writes into the limiter's storage layer directly; a code regression that switched the stored type without migrating the in-memory store.","solutions":["Confirm nothing else writes to the same memory.Storage instance; the manager creates its own via memory.New() when storage is nil, so this only happens if you injected a shared one.","If testing, use a fresh memory.Storage per limiter instance or let the limiter allocate its own (pass nil storage).","Search the codebase for any external Set on the storage backing the limiter.","Reset the in-memory store (restart the process) to clear the mistyped entry."],"exampleFix":"// before: shared memory store pollutes limiter keys\nshared := memory.New()\nshared.Set(\"limiter:1.2.3.4\", \"not-an-item\", time.Minute)\nlimiter.New(limiter.Config{Storage: shared}) // nil external storage but shared memory is not configurable here\n\n// after: let the limiter own its memory store\nlimiter.New(limiter.Config{})","handlingStrategy":"validation","validationCode":"// Ensure the limiter owns its memory store — pass nil storage so it allocates privately.\nlimiter.New(limiter.Config{}) // Storage left nil","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never inject a shared memory.Storage into the limiter.","In tests, instantiate a fresh limiter per case rather than reusing one.","Audit external code that may hold a reference to the limiter's internal storage."],"tags":["limiter","memory","type-assertion","internal"],"backgroundTag":null,"analyzedSha":"a105acad6c1e4576a77f01e02973f67e962bb58d","analyzedAt":"2026-08-11T17:33:26.942Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}