[特性] MemorySaver 在缺失 threadId 时默默回退到 "$default",导致跨会话状态互相可见

作者: z1258创建于 2026年9月16日更新于 2026年9月16日
标签needs-triage

① The storage field name itself indicates that it is partitioned by thread.

java
public class MemorySaver implements BaseCheckpointSaver {
    final Map<String, LinkedList<Checkpoint>> _checkpointsByThread;
}
② The default slot comes from the decompilation of MemorySaver.loadOrInitCheckpoints.
```java
8: invokevirtual  RunnableConfig.threadId()Ljava/util/Optional;
11: ldc            String "$default"
13: invokevirtual  Optional.orElse
24: getfield       MemorySaver._checkpointsByThread
33: invokeinterface Map.computeIfAbsent      // ← using threadId as the key
③ The behavior is inconsistent within the same framework: the following code in ReactAgent explicitly requires threadId:
```java
new IllegalArgumentException("threadId must be provided in RunnableConfig for interruption.")

内容来源: alibaba/spring-ai-alibaba