{"record":{"id":"7e187f619af0206d","repo":"thanos-io/thanos","slug":"failed-to-convert-s-resp-to-string","errorCode":null,"errorMessage":"failed to convert %s resp to string","messagePattern":"failed to convert (.+?) resp to string","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/cortex/chunk/cache/redis_client.go","lineNumber":153,"sourceCode":"\n\tret := make([][]byte, 0, len(keys))\n\n\tmgetRet, err := rueidis.MGet(c.rdb, ctx, keys)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tfor _, k := range keys {\n\t\tm, ok := mgetRet[k]\n\t\tif !ok {\n\t\t\treturn nil, errors.Errorf(\"not found key %s in results\", k)\n\t\t}\n\t\tif m.IsNil() {\n\t\t\tret = append(ret, nil)\n\t\t\tcontinue\n\t\t}\n\t\tr, err := m.ToString()\n\t\tif err != nil {\n\t\t\treturn nil, errors.Errorf(\"failed to convert %s resp to string\", k)\n\t\t}\n\t\tret = append(ret, stringToBytes(r))\n\t}\n\n\treturn ret, nil\n}\n\nfunc (c *RedisClient) Close() error {\n\tc.rdb.Close()\n\treturn nil\n}\n\nfunc stringToBytes(s string) []byte {\n\treturn *(*[]byte)(unsafe.Pointer(\n\t\t&struct {\n\t\t\tstring\n\t\t\tCap int\n\t\t}{s, len(s)},","sourceCodeStart":135,"sourceCodeEnd":171,"githubUrl":"https://github.com/thanos-io/thanos/blob/35b8b991177def87ed52dcf10f9b6d87f07282c8/internal/cortex/chunk/cache/redis_client.go#L135-L171","documentation":"RedisClient.MGet converts each non-nil MGET reply message to a string; if rueidis's m.ToString() fails for a key, the client returns this error identifying which key's reply could not be converted. It indicates the server returned an unexpected reply type (e.g. an error message) for that key.","triggerScenarios":"Calling MGet() where the reply for key k is neither nil nor a bulk/simple string — typically an error reply (WRONGTYPE, MOVED/ASK in cluster mode) surfaced as a message that cannot convert to string.","commonSituations":"Key holds a non-string Redis type (hash/list) because another writer overwrote it; cluster redirect errors when using a plain client against a cluster; corrupted proxy replies.","solutions":["Check the key named in the error with redis-cli TYPE <key> — remove/fix non-string values written by other components.","Use a cluster-aware Redis client if replies contain MOVED/ASK errors.","Harden the caller to treat conversion failures as cache misses instead of aborting the batch.","Audit writers that may store complex types under keys this cache expects to own."],"exampleFix":"// before\nr, err := m.ToString()\nif err != nil { return nil, errors.Errorf(\"failed to convert %s resp to string\", k) }\n// after\ntypeGuard = func(m rueidis.RedisMessage) bool { return !m.IsNil() && !m.IsError() }","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"func isStringReply(m rueidis.RedisMessage) bool {\n    return !m.IsNil() && !m.IsError()\n}","tryCatchPattern":"vals, err := client.MGet(ctx, keys)\nif err != nil && strings.Contains(err.Error(), \"failed to convert\") {\n    key := extractKeyFromErr(err)\n    log.Warnf(\"non-string value at %s — treat as miss\", key)\n    vals = nil\n}","preventionTips":["Ensure only this cache writes to its key namespace.","Run redis-cli TYPE on suspicious keys to catch WRONGTYPE collisions.","Use a cluster-aware client to avoid MOVED/ASK error replies."],"tags":["redis","mget","type-mismatch"],"backgroundTag":"unexpected-response-shape","analyzedSha":"35b8b991177def87ed52dcf10f9b6d87f07282c8","analyzedAt":"2026-09-07T01:49:59.689Z","contentChangedAt":"2026-09-07T01:49:59.689Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}