Human Input timeout handle drifted from “__timeout” to “__timeout__” in the backend

该报错是 Dify 前端与后端对 Human Input 节点“超时”分支的句柄标识不一致导致的:前端持久化的是 __timeout (单个下划线对),而后端在 callback.py 中硬编码为 __timeout__ (双下划线对),运行时超时决策会指向错误的边。优先检查后端 _TIMEOUT_

快速结论:该报错是 Dify 前端与后端对 Human Input 节点“超时”分支的句柄标识不一致导致的:前端持久化的是 __timeout(单个下划线对),而后端在 callback.py 中硬编码为 __timeout__(双下划线对),运行时超时决策会指向错误的边。优先检查后端 _TIMEOUT_HANDLE 常量是否与前端保持一致。

适用环境:Dify 1.16.1 及当前 main 分支(commit f785af3),Self Hosted(源码部署)模式。

最快修复方案:api/core/workflow/nodes/human_input/callback.py 第 71 行的 _TIMEOUT_HANDLE = "__timeout__" 改为 _TIMEOUT_HANDLE = "__timeout",这是 Issue 确认的单行修复。

注意事项:同步更新相关单测(如 test_human_input_form_filled_event.py)中断言 "__timeout__" 的部分;否则测试会继续验证后端内部一致性而无法防止跨层句柄漂移。

问题场景

在 Dify 工作流中创建 Human Input 节点并设置超时分支:将节点的 Timeout 分支连接到另一个节点并保存工作流后,前端持久化的 sourceHandle__timeout,但当表单真正到达节点级超时时,后端 DifyHITLCallback 返回的却是 selected_handle="__timeout__"。这会导致运行时超时决策无法匹配实际配置的超时边,甚至可能与用户操作分支(恰好使用 __timeout__ 作为有效 ID)发生冲突。

报错原文

Human Input timeout handle drifted from "__timeout" to "__timeout__" in the backend

The frontend persists the timeout edge with sourceHandle: "__timeout",
while the backend emits selected_handle="__timeout__".

The backend DifyHITLCallback returns Expired(selected_handle="__timeout__")

原因分析

可能原因:这是一次迁移回归。原始 Dify 实现的前后端都使用 __timeout;在迁移 PR #38225 中,RED 测试和实现仍为 __timeout(见 commit dbd2d2497c393c),但重写后的迁移 commit 56ff71e 开始引入尾部双下划线,最终随 #38247 合并。此次迁移改动了后端常量,但未同步改动前端句柄,造成前后端持久化标识不一致。

环境排查

  • 确认 Dify 版本是否为 1.16.1 或当前 main 分支(f785af3
  • 检查 web/app/components/workflow/nodes/human-input/node.tsxhandleId="__timeout" 是否保持不变
  • 检查 api/core/workflow/nodes/human_input/callback.py_TIMEOUT_HANDLE 常量的值
  • 查看持久化工作流 DSL 中 sourceHandle 的实际值

解决步骤

  1. 编辑 api/core/workflow/nodes/human_input/callback.py,将第 71 行 _TIMEOUT_HANDLE = "__timeout__" 改为 _TIMEOUT_HANDLE = "__timeout"。这是 Issue 确认的单行修复,backend 两处超时代码路径(显式 TIMEOUT 状态和节点截止时间检查)都会使用该常量。
  2. 同步更新单测文件 api/tests/unit_tests/core/workflow/nodes/human_input/test_human_input_form_filled_event.py 中断言 "__timeout__" 的部分(约第 260-267 行)为 "__timeout"。否则现有测试只会验证后端内部一致性,无法防止前后端句柄再次漂移。
  3. (可优先尝试)若工作流已有持久化数据,重启 Dify API 服务使改动生效;不需要迁移已有 DSL,因为前端与 DSL 中的 __timeout 本就是正确值,修复目的是让后端匹配已有数据。

验证方法

在包含 Human Input 节点的工作流中设置超时分支并保存,等待表单达到节点级超时,确认后端返回的 selected_handle__timeout,且超时分支能按预期路由。同时运行相关单测,确认更新后的断言通过。

参考来源

langgenius/dify #40459

GamsGo AI

AI 工具推荐

想把多个 AI 模型放在一个入口?

GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。

了解 GamsGo AI

推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。

这个方案解决了吗?

celebrityanime
celebrityanime
文章: 20383

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注