{"record":{"id":"06149df0abd4dfc2","repo":"kataras/iris","slug":"unknown-value-type-of-t","errorCode":null,"errorMessage":"unknown value type of %T","messagePattern":"unknown value type of %T","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sessions/sessiondb/redis/database.go","lineNumber":222,"sourceCode":"\t}\n\n\treturn nil\n}\n\nfunc (db *Database) decodeValue(val any, outPtr any) error {\n\tif val == nil {\n\t\treturn nil\n\t}\n\n\tswitch data := val.(type) {\n\tcase []byte:\n\t\t// this is the most common type, as we save all values as []byte,\n\t\t// the only exception is where the value is string on HGetAll command.\n\t\treturn sessions.DefaultTranscoder.Unmarshal(data, outPtr)\n\tcase string:\n\t\treturn sessions.DefaultTranscoder.Unmarshal([]byte(data), outPtr)\n\tdefault:\n\t\treturn fmt.Errorf(\"unknown value type of %T\", data)\n\t}\n}\n\nfunc (db *Database) keys(fullSID string) []string {\n\tkeys, err := db.c.Driver.GetKeys(fullSID)\n\tif err != nil {\n\t\tdb.logger.Debugf(\"unable to get all redis keys of session '%s': %v\", fullSID, err)\n\t\treturn nil\n\t}\n\n\treturn keys\n}\n\n// Visit loops through all session keys and values.\nfunc (db *Database) Visit(sid string, cb func(key string, value any)) error {\n\tkv, err := db.c.Driver.GetAll(db.makeSID(sid))\n\tif err != nil {\n\t\treturn err","sourceCodeStart":204,"sourceCodeEnd":240,"githubUrl":"https://github.com/kataras/iris/blob/7bedaf55a0b64bbb2248a5845a2c60d81a30996a/sessions/sessiondb/redis/database.go#L204-L240","documentation":"The Redis session database's decodeValue switches on the dynamic type returned from Redis: []byte (the common case) or string (from HGetAll). Any other type stored or returned cannot be decoded into the caller's out pointer, so it fails with this error reporting the unexpected Go type via %T.","triggerScenarios":"Decode/Visit on a Redis-backed session DB when the raw value stored in Redis is neither []byte nor string — typically after data was written by a different client/tool or a different session library version.","commonSituations":"Manually seeding Redis session keys with native Redis types (lists, hashes, ints via redis-cli), upgrading iris/sessions versions with old serialized values, or mixing transcoders between writers and readers.","solutions":["Ensure session values are always written through the same Database/Transcoder so they are stored as []byte.","Clear the affected Redis keys (FLUSHDB or targeted DEL) so stale/foreign values are removed.","Inspect the offending key's Redis TYPE; if it's hash/list/etc. set by external code, migrate it to a plain string/[]byte.","Use a compatible DefaultTranscoder on both the writing and reading sides."],"exampleFix":"// before (external write)\nredis-cli HSET sessions:sid key value\n// after\nsess.Set(\"key\", \"value\") // library encodes as []byte internally","handlingStrategy":"try-catch","validationCode":"t, err := rdb.Type(ctx, \"sessions:\"+sid).Result()\nif t != \"string\" {\n    return fmt.Errorf(\"session key has redis type %q; expected string\", t)\n}","typeGuard":"func decodable(v any) bool {\n    switch v.(type) {\n    case []byte, string:\n        return true\n    }\n    return false\n}","tryCatchPattern":"if err := db.Decode(key, out); err != nil {\n    if strings.HasPrefix(err.Error(), \"unknown value type of\") {\n        // purge foreign-format key and re-create session\n        rdb.Del(ctx, key)\n        return newSession()\n    }\n    return err\n}","preventionTips":["Write session values only through the library's Set/Update APIs, never raw redis-cli.","Keep the same sessions transcoder across all services sharing the Redis DB.","Flush or version-prefix session keys when upgrading serialization formats."],"tags":["redis","sessions","deserialization"],"backgroundTag":"unknown-value-type","analyzedSha":"7bedaf55a0b64bbb2248a5845a2c60d81a30996a","analyzedAt":"2026-08-30T20:38:16.250Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}