{"id":"02fe01ec98e5c86f","repo":"go-redis/redis","slug":"redis-unexpected-type-t-for-int","errorCode":null,"errorMessage":"redis: unexpected type=%T for Int","messagePattern":"redis: unexpected type=%T for Int","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"command.go","lineNumber":667,"sourceCode":"\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}\n}\n\nfunc (cmd *Cmd) Int64() (int64, error) {\n\tcmd.await()\n\tif cmd.err != nil {\n\t\treturn 0, cmd.err\n\t}\n\treturn toInt64(cmd.val)\n}\n\nfunc toInt64(val interface{}) (int64, error) {\n\tswitch val := val.(type) {\n\tcase int64:\n\t\treturn val, nil\n\tcase string:\n\t\treturn strconv.ParseInt(val, 10, 64)","sourceCodeStart":649,"sourceCodeEnd":685,"githubUrl":"https://github.com/go-redis/redis/blob/36d97525cd8076aed67cddf54778e9ea84550929/command.go#L649-L685","documentation":"Returned by Cmd.Int() (command.go:661) when the reply value is neither int64 nor string. Int() accepts int64 (from an integer reply) and string (parsed via strconv.Atoi); anything else (array, nil, bulk-of-wrong-shape) yields this error. It signals the reply did not carry a single numeric scalar.","triggerScenarios":"Calling Int() on a raw Cmd whose reply is an array (e.g. Do EXEC on a pipeline reply) or nil; calling Int() where the command actually returns a status/bulk that is non-numeric; calling Int() after an INCR but on a Cmd that was reused for a different command type.","commonSituations":"Reusing the generic Cmd from Do for a multi-element reply; expecting an integer reply from a command that returns a count-in-array; forgetting to handle redis.Nil (which returns before this switch only if cmd.err was set — but a present non-integer val still falls through).","solutions":["Use the typed command (e.g. client.Incr → IntCmd; client.Del → IntCmd) so the reply parser sets an int64 directly.","Call cmd.Result() and type-switch on interface{} before converting.","Verify cmd.Err() (including redis.Nil) before reading the value."],"exampleFix":"// before\nn, err := client.Do(ctx, \"DBSIZE\").Int() // DBSIZE is integer → ok, but a Do over a non-int reply is not\n\n// after — typed accessor\nn, err := client.DbSize(ctx).Result()","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"func asInt(cmd *redis.Cmd) (int, error) {\n    if err := cmd.Err(); err != nil { return 0, err }\n    switch v := cmd.Val().(type) {\n    case int64:\n        return int(v), nil\n    case string:\n        return strconv.Atoi(v)\n    default:\n        return 0, fmt.Errorf(\"not an int: %T\", v)\n    }\n}","tryCatchPattern":"n, err := cmd.Int()\nif err != nil && strings.Contains(err.Error(), \"unexpected type\") {\n    // reply was not an integer scalar — use the typed command\n}","preventionTips":["Use IntCmd-returning methods (Incr, Decr, Del, StrLen) for integer replies.","Type-switch on Result() when using Do.","Validate cmd.Err() before reading the value."],"tags":["command","type-conversion","reply-parsing","api-misuse"],"analyzedSha":"36d97525cd8076aed67cddf54778e9ea84550929","analyzedAt":"2026-08-06T01:08:27.376Z","schemaVersion":2}