agentscope-ai / agentscope-ai/agentscope-java

[Bug]:`ERR 'EVAL' command keys must in same slot` in Redis Cluster

Open
#2,165 1 comment 0 reactions 0 assignees View on GitHub
area/extensions bug
Dominant language
Java
Stars
5.6k
Forks
1.3k
Avg merge
4d 12h
Merged PRs (30d)
77

Description

### 🐞 Bug Report: `ERR 'EVAL' command keys must in same slot` in Redis Cluster

**Describe the bug**
The `RedisStore` implementation fails when running against a Redis Cluster. The `put` operation executes a Lua script (`EVAL`) involving two keys: the item hash key and the namespace index key. Since these keys have different prefixes (`item:` vs `idx:`), they are hashed to different slots in the cluster, causing the `EVAL` command to fail with `ERR 'EVAL' command keys must in same slot`.

**To Reproduce**
1. Configure the application to connect to a Redis Cluster (not a standalone instance).
2. Initialize the `RedisStore` class.
3. Call the `put` method to store an item.
```java
store.put(Arrays.asList("test", "namespace"), "my-key", myValueMap);
```
4. See the error in the logs.

**Expected behavior**
The `put` operation should succeed. The item hash and the namespace index should be stored atomically. To support Redis Cluster, the keys used in the Lua script must belong to the same hash slot (typically achieved by using hash tags like `{...}` in the key names).

**Error messages**
```text
redis.clients.jedis.exceptions.JedisDataException: ERR 'EVAL' command keys must in same slot
at redis.clients.jedis.Protocol.processError(Protocol.java:110)
at redis.clients.jedis.Protocol.process(Protocol.java:158)
at redis.clients.jedis.Protocol.read(Protocol.java:221)
at redis.clients.jedis.Connection.protocolRead(Connection.java:384)
at redis.clients.jedis.Connection.readProtocolWithCheckingBroken(Connection.java:397)
at redis.clients.jedis.Connection.getOne(Connection.java:370)
at redis.clients.jedis.Connection.executeCommand(Connection.java:175)
at redis.clients.jedis.executors.DefaultCommandExecutor.executeCommand(DefaultCommandExecutor.java:24)
at redis.clients.jedis.UnifiedJedis.executeCommand(UnifiedJedis.java:311)
at redis.clients.jedis.UnifiedJedis.eval(UnifiedJedis.java:3478)
at io.agentscope.extensions.redis.store.RedisStore.put(RedisStore.java:145)
...
```

**Environment (please complete the following information):**
- **AgentScope-Java Version:** [2.0.0]
- **Java Version:** [7]
- **OS:** [linux]
- **Redis Mode:** Cluster

**Additional context**
The issue lies in the `RedisStore.java` file. The `put` method calls:
```java
jedis.eval(PUT_SCRIPT, List.of(itemKey, idxKey), List.of(json, key));
```
The `itemKey` is generated as `prefix:item:\0` and `idxKey` as `prefix:idx:`.
Because the constant parts `item:` and `idx:` differ, `CRC16(itemKey) != CRC16(idxKey)`.

**Suggested Fix:**
Modify `itemKey` and `indexKey` methods to wrap the namespace part in curly braces `{}` to force them into the same slot.
```java
// Example Fix
private String itemKey(List namespace, String key) {
String nsPath = namespacePath(namespace);
// Use hash tag {nsPath} to ensure co-location
return keyPrefix + "item:{" + nsPath + "}" + NS_SEPARATOR + key;
}

private String indexKey(List namespace) {
String nsPath = namespacePath(namespace);
// Use hash tag {nsPath}
return keyPrefix + "idx:{" + nsPath + "}";
}
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.