go-redis/redis · error
redis: unexpected type=%T for String
Error message
redis: unexpected type=%T for String
What it means
Returned by Cmd.Text() (via toString, command.go:646) when the reply value stored in the Cmd is not a Go string. toString only accepts the string RESP scalar type; any other concrete type (e.g. []interface{} from an array reply, or nil) yields this error. It indicates the wrong accessor was used for the reply shape the command actually produced.
Source
Thrown at command.go:651
func (cmd *Cmd) Result() (interface{}, error) {
cmd.await()
return cmd.val, cmd.err
}
func (cmd *Cmd) Text() (string, error) {
cmd.await()
if cmd.err != nil {
return "", cmd.err
}
return toString(cmd.val)
}
func toString(val interface{}) (string, error) {
switch val := val.(type) {
case string:
return val, nil
default:
err := fmt.Errorf("redis: unexpected type=%T for String", val)
return "", err
}
}
func (cmd *Cmd) Int() (int, error) {
cmd.await()
if cmd.err != nil {
return 0, cmd.err
}
switch val := cmd.val.(type) {
case int64:
return int(val), nil
case string:
return strconv.Atoi(val)
default:
err := fmt.Errorf("redis: unexpected type=%T for Int", val)
return 0, err
}View on GitHub (pinned to 36d97525cd)
Solutions
- Use the typed command method that matches the reply shape (e.g. client.HGetAll → a StringStringMapCmd; client.LRange → StringSliceCmd).
- If using Do(), call cmd.Result() and type-switch on the returned interface{} before coercing.
- Check cmd.Err() first and handle redis.Nil before accessing the value.
Example fix
// before res, err := client.Do(ctx, "HGETALL", "k").Text() // HGETALL returns an array → error // after m, err := client.HGetAll(ctx, "k").Result() // StringStringMapCmd, correct shape
Defensive patterns
Strategy: type-guard
Type guard
func asString(cmd *redis.Cmd) (string, error) {
if err := cmd.Err(); err != nil { return "", err }
switch v := cmd.Val().(type) {
case string:
return v, nil
default:
return "", fmt.Errorf("not a string: %T", v)
}
} Try / catch
s, err := cmd.Text()
if err != nil && strings.Contains(err.Error(), "unexpected type") {
// wrong accessor for the reply shape — switch to a typed command
} Prevention
- Prefer the typed command method (HGetAll, Get, LRange) over Do() + Text().
- Type-switch on cmd.Result() before coercing raw Do replies.
- Handle redis.Nil before reading the value.
When it happens
Trigger: Calling cmd.Text() on a Cmd that holds an array reply — e.g. issuing Do(ctx, "HGETALL", key) (raw Cmd) and calling Text(); calling Text() on a nil val when an earlier nil-check was skipped; calling Text() on a result whose accessor should be Slice()/Int64Slice().
Common situations: Using the generic Cmd from client.Do or client.Process for a command that returns a non-string reply instead of the typed Cmd (e.g. StringSliceCmd, XMessageSliceCmd); mis-typing a command that returns an integer/array.
Related errors
- redis: unexpected type=%T for Int
- redis: unexpected type=%T for Int64
- redis: unexpected type=%T for Uint64
- redis: unexpected type=%T for Float32
- redis: unexpected type=%T for Float64
AI-assisted analysis of go-redis/redis@36d97525cd (2026-08-06).
Data as JSON: /data/errors/686ae5e1619235cc.json.
Report an issue: GitHub.