mirror of
https://github.com/langgenius/dify.git
synced 2026-10-04 13:47:55 +08:00
Streaming introduced a correctness regression: if the event stream ended without a terminal frame (idle timeout, dead publishing worker), run_draft synthesised status="failed" with an empty dify_run_id. A run that had in fact SUCCEEDED would then be reported as a failed build and sent into the repair loop. The blocking path would have waited and returned the truth. The stream is the fast path, not the authority. Every non-ping frame is stamped with workflow_run_id by convert_stream_full_response, so the run id is known from the first frame onwards -- long before the terminal frame that may never arrive. run_draft now captures it from any frame and, when no terminal frame arrives, reads the run's real status from the workflow-run row instead of inventing one. Note that data["id"] is the node-execution id on node frames, not the run id, so it is only read as a run id on workflow-level frames. When even the row cannot settle it -- no run id, no row, or a row still marked running because the worker died mid-run -- the result is reported as status="running" with an explicit Run.error, which is what Run.status already documents for "not over / not known". A truncated stream is now either the truth or a visible unknown, never a fabricated failure. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>