From 0313ea0238571bcd7fab890ce45e287b3d062413 Mon Sep 17 00:00:00 2001 From: Classic298 <27028174+Classic298@users.noreply.github.com> Date: Sat, 12 Sep 2026 20:55:13 +0200 Subject: [PATCH] fix: stop every task of a chat when stopping a response without Redis (#29844) Pressing Stop on a chat that has more than one running task (a multi-model response, or a follow-up sent from another tab or device while a response is still streaming) reported success but only cancelled the first task. The survivors kept streaming and kept executing tool calls until the iteration limit, which is the runaway reported in the issue. Without Redis the stop loop iterates the live task-id list of the chat. Each awaited cancellation runs that task's cleanup, which removes its id from the same list mid-iteration, so the loop runs out one element early and the last task is never cancelled. Returning a snapshot of the list to callers keeps the loop on the ids it started with. Redis deployments already got a fresh list from the set and were not affected. Verified against a mock upstream that calls a tool on every turn: with three tasks on one chat, stop left one or two alive before the change and cancels all of them after it. Fixes #29816 --- backend/open_webui/tasks.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/open_webui/tasks.py b/backend/open_webui/tasks.py index 1fe268296e..6a1d6df84f 100644 --- a/backend/open_webui/tasks.py +++ b/backend/open_webui/tasks.py @@ -166,7 +166,7 @@ async def list_task_ids_by_item_id(redis, id): """ if redis: return await redis_list_item_tasks(redis, id) - return item_tasks.get(id, []) + return list(item_tasks.get(id, [])) async def save_response_stream(