{"id":"686ae5e1619235cc","repo":"go-redis/redis","slug":"redis-unexpected-type-t-for-string","errorCode":null,"errorMessage":"redis: unexpected type=%T for String","messagePattern":"redis: unexpected type=%T for String","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"command.go","lineNumber":651,"sourceCode":"func (cmd *Cmd) Result() (interface{}, error) {\n\tcmd.await()\n\treturn cmd.val, cmd.err\n}\n\nfunc (cmd *Cmd) Text() (string, error) {\n\tcmd.await()\n\tif cmd.err != nil {\n\t\treturn \"\", cmd.err\n\t}\n\treturn toString(cmd.val)\n}\n\nfunc toString(val interface{}) (string, error) {\n\tswitch val := val.(type) {\n\tcase string:\n\t\treturn val, nil\n\tdefault:\n\t\terr := fmt.Errorf(\"redis: unexpected type=%T for String\", val)\n\t\treturn \"\", err\n\t}\n}\n\nfunc (cmd *Cmd) Int() (int, error) {\n\tcmd.await()\n\tif cmd.err != nil {\n\t\treturn 0, cmd.err\n\t}\n\tswitch val := cmd.val.(type) {\n\tcase int64:\n\t\treturn int(val), nil\n\tcase string:\n\t\treturn strconv.Atoi(val)\n\tdefault:\n\t\terr := fmt.Errorf(\"redis: unexpected type=%T for Int\", val)\n\t\treturn 0, err\n\t}","sourceCodeStart":633,"sourceCodeEnd":669,"githubUrl":"https://github.com/go-redis/redis/blob/36d97525cd8076aed67cddf54778e9ea84550929/command.go#L633-L669","documentation":"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.","triggerScenarios":"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().","commonSituations":"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.","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."],"exampleFix":"// before\nres, err := client.Do(ctx, \"HGETALL\", \"k\").Text() // HGETALL returns an array → error\n\n// after\nm, err := client.HGetAll(ctx, \"k\").Result() // StringStringMapCmd, correct shape","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"func asString(cmd *redis.Cmd) (string, error) {\n    if err := cmd.Err(); err != nil { return \"\", err }\n    switch v := cmd.Val().(type) {\n    case string:\n        return v, nil\n    default:\n        return \"\", fmt.Errorf(\"not a string: %T\", v)\n    }\n}","tryCatchPattern":"s, err := cmd.Text()\nif err != nil && strings.Contains(err.Error(), \"unexpected type\") {\n    // wrong accessor for the reply shape — switch to a typed command\n}","preventionTips":["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."],"tags":["command","type-conversion","reply-parsing","api-misuse"],"analyzedSha":"36d97525cd8076aed67cddf54778e9ea84550929","analyzedAt":"2026-08-06T01:08:27.376Z","schemaVersion":2}