gofr-dev/gofr · error

unexpected Redis result type

Error message

unexpected Redis result type

What it means

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.

Source

Thrown at pkg/gofr/service/rate_limiter_config.go:13

package service

import (
	"errors"
	"fmt"
	"net/http"
	"time"
)

var (
	errInvalidRequestRate     = errors.New("requests must be greater than 0 per configured time window")
	errBurstLessThanRequests  = errors.New("burst must be greater than requests per window")
	errInvalidRedisResultType = errors.New("unexpected Redis result type")
)

const (
	unknownServiceKey = "unknown"
	methodHTTP        = "http"
	methodHTTPS       = "https"
)

// RateLimiterConfig with custom keying support.
type RateLimiterConfig struct {
	Requests float64                    // Number of requests allowed
	Window   time.Duration              // Time window (e.g., time.Minute, time.Hour)
	Burst    int                        // Maximum burst capacity (must be > 0)
	KeyFunc  func(*http.Request) string // Optional custom key extraction
	Store    RateLimiterStore
}

// defaultKeyFunc extracts a normalized service key from an HTTP request.

View on GitHub (pinned to 187eb24962)

Solutions

  1. 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).
  2. If you upgraded the Redis library, adapt the store layer to map new result types to int64.
  3. For custom RateLimiterStore implementations, normalize all return values to standard integer types.
  4. Add a unit test mirroring TestRedisRateLimiterStore_toInt64_ErrorCases to pin the accepted types.

Example fix

// before
return store.Eval(ctx, script, keys, args) // returns redis.Results, unmapped
// after
v, err := store.Eval(ctx, script, keys, args).Int64()
if err != nil { return 0, err }
return v, nil
Defensive patterns

Strategy: type-guard

Validate before calling

// normalize Redis replies before handing them to the store
v, err := redisClient.Get(ctx, key).Int64()
if err != nil { return 0, err }

Type guard

func toInt64Safe(v any) (int64, bool) {
	switch n := v.(type) {
	case int64:
		return n, true
	case int:
		return int64(n), true
	case []byte:
		n2, err := strconv.ParseInt(string(n), 10, 64)
		return n2, err == nil
	case string:
		n2, err := strconv.ParseInt(n, 10, 64)
		return n2, err == nil
	}
	return 0, false
}

Try / catch

allowed, err := store.Allow(ctx, key, limit)
if errors.Is(err, errInvalidRedisResultType) {
	return false, fmt.Errorf("redis store returned unexpected type for key %s: %w", key, err)
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of gofr-dev/gofr@187eb24962 (2026-09-01). Data as JSON: /api/errors/7f1d8827cb2e9ddb. Report an issue: GitHub.