{"record":{"id":"7f1d8827cb2e9ddb","repo":"gofr-dev/gofr","slug":"unexpected-redis-result-type","errorCode":null,"errorMessage":"unexpected Redis result type","messagePattern":"unexpected Redis result type","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/gofr/service/rate_limiter_config.go","lineNumber":13,"sourceCode":"package service\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"time\"\n)\n\nvar (\n\terrInvalidRequestRate     = errors.New(\"requests must be greater than 0 per configured time window\")\n\terrBurstLessThanRequests  = errors.New(\"burst must be greater than requests per window\")\n\terrInvalidRedisResultType = errors.New(\"unexpected Redis result type\")\n)\n\nconst (\n\tunknownServiceKey = \"unknown\"\n\tmethodHTTP        = \"http\"\n\tmethodHTTPS       = \"https\"\n)\n\n// RateLimiterConfig with custom keying support.\ntype RateLimiterConfig struct {\n\tRequests float64                    // Number of requests allowed\n\tWindow   time.Duration              // Time window (e.g., time.Minute, time.Hour)\n\tBurst    int                        // Maximum burst capacity (must be > 0)\n\tKeyFunc  func(*http.Request) string // Optional custom key extraction\n\tStore    RateLimiterStore\n}\n\n// defaultKeyFunc extracts a normalized service key from an HTTP request.","sourceCodeStart":1,"sourceCodeEnd":31,"githubUrl":"https://github.com/gofr-dev/gofr/blob/187eb24962502e91f1fee856230670958b66e89c/pkg/gofr/service/rate_limiter_config.go#L1-L31","documentation":"errInvalidRedisResultType (rate_limiter_config.go:13) is returned when converting a Redis reply to int64 fails — toInt64 (used by the Redis RateLimiterStore / Allow) received a type it doesn't recognize (not int64, int, []byte, string, etc.). It indicates a contract mismatch between the Redis client version/output format and the limiter's expectations.","triggerScenarios":"Allow/toInt64 processing a Redis store reply of an unexpected Go type — e.g. a custom RateLimiterStore returning unexpected values, a Redis client returning a different result shape than expected, or nil/nilable replies surfacing as an unmapped type; exercised by TestRedisRateLimiterStore_toInt64_ErrorCases.","commonSituations":"Swapping or upgrading the Redis client library so EVAL/lua script results arrive as a different type; implementing a custom RateLimiterStore whose Get/Incr returns exotic types; stub stores in tests returning unexpected values.","solutions":["Check what type your Redis client actually returns for the rate-limit command and ensure it is one of int64/int/string/[]byte (or convert in your store before returning).","If you upgraded the Redis library, adapt the store layer to map new result types to int64.","For custom RateLimiterStore implementations, normalize all return values to standard integer types.","Add a unit test mirroring TestRedisRateLimiterStore_toInt64_ErrorCases to pin the accepted types."],"exampleFix":"// before\nreturn store.Eval(ctx, script, keys, args) // returns redis.Results, unmapped\n// after\nv, err := store.Eval(ctx, script, keys, args).Int64()\nif err != nil { return 0, err }\nreturn v, nil","handlingStrategy":"type-guard","validationCode":"// normalize Redis replies before handing them to the store\nv, err := redisClient.Get(ctx, key).Int64()\nif err != nil { return 0, err }","typeGuard":"func toInt64Safe(v any) (int64, bool) {\n\tswitch n := v.(type) {\n\tcase int64:\n\t\treturn n, true\n\tcase int:\n\t\treturn int64(n), true\n\tcase []byte:\n\t\tn2, err := strconv.ParseInt(string(n), 10, 64)\n\t\treturn n2, err == nil\n\tcase string:\n\t\tn2, err := strconv.ParseInt(n, 10, 64)\n\t\treturn n2, err == nil\n\t}\n\treturn 0, false\n}","tryCatchPattern":"allowed, err := store.Allow(ctx, key, limit)\nif errors.Is(err, errInvalidRedisResultType) {\n\treturn false, fmt.Errorf(\"redis store returned unexpected type for key %s: %w\", key, err)\n}","preventionTips":["Convert Redis replies to int64 in your store adapter, not at the limiter layer.","Pin and test the Redis client version — upgrades can change result types.","Implement custom RateLimiterStore methods to return only standard integer types.","Mirror TestRedisRateLimiterStore_toInt64_ErrorCases for any new result type you support."],"tags":["redis","rate-limiting","type-mismatch"],"backgroundTag":"unexpected-redis-result-type","analyzedSha":"187eb24962502e91f1fee856230670958b66e89c","analyzedAt":"2026-09-01T20:34:54.554Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}