{"record":{"id":"b17fbd7671cb06e9","repo":"redis/jedis","slug":"key-tostring-is-not-a-valid-argument","errorCode":null,"errorMessage":"\"${key.toString()}\" is not a valid argument.","messagePattern":"\"(.+?)\" is not a valid argument\\.","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/main/java/redis/clients/jedis/CommandArguments.java","lineNumber":148,"sourceCode":"    if (keyPreProc != null) {\n      key = keyPreProc.actualKey(key);\n    }\n\n    if (key instanceof Rawable) {\n      Rawable raw = (Rawable) key;\n      args.add(raw);\n      // Extract raw bytes for hash slot computation to avoid ClassCastException in getKeyHashSlots()\n      addHashSlotKey(raw.getRaw());\n    } else if (key instanceof byte[]) {\n      byte[] raw = (byte[]) key;\n      args.add(RawableFactory.from(raw));\n      addHashSlotKey(raw);\n    } else if (key instanceof String) {\n      String raw = (String) key;\n      args.add(RawableFactory.from(raw));\n      addHashSlotKey(raw);\n    } else {\n      throw new IllegalArgumentException(\"\\\"\" + key.toString() + \"\\\" is not a valid argument.\");\n    }\n\n    return this;\n  }\n\n  final CommandArguments addHashSlotKey(String key) {\n    keys.add(key);\n    // Invalidate cached hash slots since keys have changed\n    cachedHashSlots = null;\n    return this;\n  }\n\n  final CommandArguments addHashSlotKey(byte[] key) {\n    keys.add(key);\n    // Invalidate cached hash slots since keys have changed\n    cachedHashSlots = null;\n    return this;\n  }","sourceCodeStart":130,"sourceCodeEnd":166,"githubUrl":"https://github.com/redis/jedis/blob/6dac31d4c224fb3257c216f3985340c6f500cdcb/src/main/java/redis/clients/jedis/CommandArguments.java#L130-L166","documentation":"CommandArguments.key(Object) converts a command's key into wire bytes but only supports byte[], String, and Rawable key objects. Any other object type passed as a key is rejected with an IllegalArgumentException that echoes the object's toString().","triggerScenarios":"Calling stream commands such as xread/xreadGroup (which pass keys into CommandArguments.key) with a key that is not byte[], String, or Rawable — e.g. a StreamEntryID, a numeric ID, or a custom key object.","commonSituations":"Passing a stream name wrapped in a custom type; accidentally passing a StreamEntryID or Map entry where the stream key string was expected; framework code interpolating keys as non-String objects.","solutions":["Convert the key with key.toString() or SafeEncoder.encode(key) before passing it.","For xread/xreadGroup, ensure the first argument is the stream key (String/byte[]) and the StreamEntryID is passed in the expected map/parameter position.","If the key is a domain object, add a method returning its Redis key string and use that."],"exampleFix":"// before\njedis.xread(mapOf(entryId, streamKeyObject)); // wrong type in key position\n// after\nMap<String, StreamEntryID> streams = new HashMap<>();\nstreams.put(streamKeyObject.toString(), entryId);\njedis.xread(streams, XReadParams.xReadParams().block(1000));","handlingStrategy":"type-guard","validationCode":"static String asRedisKey(Object key) {\n  if (key instanceof String) return (String) key;\n  if (key instanceof byte[]) return SafeEncoder.encode((byte[]) key);\n  if (key == null) throw new IllegalArgumentException(\"key is null\");\n  return key.toString();\n}","typeGuard":"static boolean isValidKey(Object k) {\n  return k instanceof String || k instanceof byte[] || k instanceof redis.clients.jedis.args.Rawable;\n}","tryCatchPattern":"try {\n  jedis.xread(streams, params);\n} catch (IllegalArgumentException e) {\n  if (e.getMessage().contains(\"is not a valid argument\")) {\n    // rebuild with keys converted via asRedisKey()\n  } else throw e;\n}","preventionTips":["Pass stream names as plain Strings to xread/xreadGroup.","Keep StreamEntryID values in the ID parameter/map, never in the key position.","Normalize keys through a single helper before any command call."],"tags":["invalid-argument","key-encoding","streams"],"backgroundTag":"invalid-argument-value","analyzedSha":"6dac31d4c224fb3257c216f3985340c6f500cdcb","analyzedAt":"2026-09-08T04:55:01.204Z","contentChangedAt":"2026-09-08T04:55:01.204Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}