Skip to content

[BUG] Missing threadId silently shares the default checkpoint namespace across callers #154

Open

Description

@Aias00

背景

这是上游遗留问题 alibaba/spring-ai-alibaba#4975。在当前 ARGI main(7a0bf414b)中仍可离线复现。

当前行为

RunnableConfig 未提供 threadId 时,BaseCheckpointSaver#checkpointThreadId 会静默回退到全局常量 "$default":

  • argi-graph-core/.../BaseCheckpointSaver.java:30,58-65
  • argi-graph-core/.../MemorySaver.java:69-75

因此,同一个 saver 实例上所有未设置 threadId 的调用共享同一个 checkpoint bucket。调用方 B 即使从未写入过状态,也能读到调用方 A 的 checkpoint。

最小复现

MemorySaver saver = new MemorySaver();
RunnableConfig userA = RunnableConfig.builder().build();
RunnableConfig userB = RunnableConfig.builder().build();

saver.put(userA, Checkpoint.builder()
        .state(Map.of("owner", "USER_A", "secret", "private"))
        .nodeId("node-a")
        .nextNodeId(StateGraph.END)
        .build());

assertThat(saver.get(userB)).isPresent();
assertThat(saver.get(userB).orElseThrow().getState())
        .containsEntry("owner", "USER_A")
        .containsEntry("secret", "private");

本地验证结果:JDK 17,argi-graph-core,测试通过并确认 B 读取到了 A 的状态;无需模型、API Key 或外部服务。

影响

  • 多用户/多租户服务如果漏传 threadId,可能发生跨请求、跨用户的上下文可见。
  • 当前行为没有日志或异常,问题通常表现为“Agent 莫名继承了别的会话”。
  • CompileConfig 默认注册 MemorySaver,误用门槛较低。

期望

至少消除“静默共享”这一点,同时评估兼容性:

  1. 缺少 threadId 时输出明确 warning;或
  2. 提供严格模式,在持久化/生产配置中要求显式 threadId;并
  3. 在 checkpoint 文档中明确 "$default" 的共享语义。

如果保留默认 bucket 以兼容单用户 demo,也应让生产误用可被及时发现。

验收建议

  • 增加不依赖外部服务的回归测试,覆盖两个缺少 threadId 的独立配置。
  • 覆盖 MemorySaver,并确认其他 saver 通过共享的 checkpointThreadId 规则得到一致处理。
  • 明确有 appName/userId 元数据但缺少 threadId 时的预期行为。

Activity

  1. added
    kind/bug缺陷:实际行为与预期不符
    area/persistence持久化:状态存储、检查点与中断恢复
    area/security安全:执行权限、数据保护与内容信任边界
    needs-triage待分诊:尚需确认类型、领域或优先级
    on Oct 13, 2026
  2. Carl-Zhou-CN commented on Oct 15, 2026

    @Carl-Zhou-CN

    Assign to me

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area/persistence持久化:状态存储、检查点与中断恢复area/security安全:执行权限、数据保护与内容信任边界kind/bug缺陷:实际行为与预期不符needs-triage待分诊:尚需确认类型、领域或优先级

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions