{"id":"353c676515f84bbe","repo":"labstack/echo","slug":"errinvalidkeytype","errorCode":"ErrInvalidKeyType","errorMessage":"invalid key type","messagePattern":"invalid key type","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"context_generic.go","lineNumber":12,"sourceCode":"// SPDX-License-Identifier: MIT\n// SPDX-FileCopyrightText: © 2015 LabStack LLC and Echo contributors\n\npackage echo\n\nimport \"errors\"\n\n// ErrNonExistentKey is error that is returned when key does not exist\nvar ErrNonExistentKey = errors.New(\"non existent key\")\n\n// ErrInvalidKeyType is error that is returned when the value is not castable to expected type.\nvar ErrInvalidKeyType = errors.New(\"invalid key type\")\n\n// ContextGet retrieves a value from the context store or ErrNonExistentKey error the key is missing.\n// Returns ErrInvalidKeyType error if the value is not castable to type T.\nfunc ContextGet[T any](c *Context, key string) (T, error) {\n\tc.lock.RLock()\n\tdefer c.lock.RUnlock()\n\n\tval, ok := c.store[key]\n\tif !ok {\n\t\tvar zero T\n\t\treturn zero, ErrNonExistentKey\n\t}\n\n\ttyped, ok := val.(T)\n\tif !ok {\n\t\tvar zero T\n\t\treturn zero, ErrInvalidKeyType\n\t}","sourceCodeStart":1,"sourceCodeEnd":30,"githubUrl":"https://github.com/labstack/echo/blob/05489dc1730161df26b72d1ae2a3ba6fb8178fc7/context_generic.go#L1-L30","documentation":"ErrInvalidKeyType is returned by the generic ContextGet[T] / ContextGetOr[T] when the key exists in the context store but the stored value cannot be type-asserted to T. This happens when one part of the code stores a value of one type and another reads it with a different generic type parameter.","triggerScenarios":"Calling c.Set(\"data\", someString) in one middleware and echo.ContextGet[int](c, \"data\") in another. Or storing a *User and reading with echo.ContextGet[User].","commonSituations":"Type drift between writer and reader (e.g. refactoring a struct from value to pointer but not updating all readers). Two middlewares using the same key string for different value types.","solutions":["Ensure the type parameter T in ContextGet[T] exactly matches the type passed to c.Set (including pointer-ness)","Use a typed constant/helper for the key and type to keep writer and reader in sync","Check errors.Is(err, echo.ErrInvalidKeyType) to handle this specifically"],"exampleFix":"// before — type mismatch\nc.Set(\"user\", &User{})\nu, _ := echo.ContextGet[User](c, \"user\") // ErrInvalidKeyType\n\n// after\nc.Set(\"user\", &User{})\nu, _ := echo.ContextGet[*User](c, \"user\")","handlingStrategy":"type-guard","validationCode":"// Inspect the stored type before asserting\nraw := c.Get(\"user\")\nif raw != nil {\n    fmt.Printf(\"stored type: %T\\n\", raw)\n}","typeGuard":"// Centralize the get with a consistent type\nfunc GetUser(c echo.Context) (*User, error) {\n    return echo.ContextGet[*User](c, \"user\")\n}\n// Always call c.Set(\"user\", &User{...}) to match","tryCatchPattern":"val, err := echo.ContextGet[User](c, \"user\")\nif err != nil {\n    if errors.Is(err, echo.ErrInvalidKeyType) {\n        log.Printf(\"type mismatch for key 'user': stored %T\", c.Get(\"user\"))\n    }\n    return val, err\n}","preventionTips":["Keep the type argument T in ContextGet[T] consistent with the value type in c.Set (match pointer-ness)","Create wrapper get/set helpers per key to enforce type consistency","Avoid reusing the same key string for different value types across middlewares"],"tags":["context-store","generics","type-mismatch","type-assertion"],"analyzedSha":"05489dc1730161df26b72d1ae2a3ba6fb8178fc7","analyzedAt":"2026-08-04T21:32:47.783Z","schemaVersion":2}