[特性] MemorySaver 在缺失 threadId 时默默回退到 "$default",导致跨会话状态互相可见
作者: z1258创建于 2026年9月16日更新于 2026年9月16日
标签needs-triage
① The storage field name itself indicates that it is partitioned by thread.
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