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

  1. Use the typed command method that matches the reply shape (e.g. client.HGetAll → a StringStringMapCmd; client.LRange → StringSliceCmd).
  2. If using Do(), call cmd.Result() and type-switch on the returned interface{} before coercing.
  3. 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

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


AI-assisted analysis of go-redis/redis@36d97525cd (2026-08-06). Data as JSON: /data/errors/686ae5e1619235cc.json. Report an issue: GitHub.