From bfc606a9e3065065bd9bfe4e1e9206236a94e987 Mon Sep 17 00:00:00 2001 From: Classic298 <27028174+Classic298@users.noreply.github.com> Date: Wed, 25 Mar 2026 22:56:43 +0100 Subject: [PATCH] fix: align file context injection by user-role messages for native FC (#22776) The add_file_context function used a positional zip() to pair API payload messages with DB-stored messages. After process_messages_with_output() expands assistant messages containing tool calls into multiple OpenAI-format messages (assistant + tool results), the payload list becomes longer than the stored list. This caused the zip to misalign, so subsequent user messages never received their attached_files tags -- the model could see uploaded images via vision but had no file URL to pass to edit_image. Fix: filter both lists to user-role messages only before zipping. User messages maintain the same order in both lists regardless of assistant message expansion, restoring correct file context injection. Fixes #21878 --- backend/open_webui/utils/middleware.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/backend/open_webui/utils/middleware.py b/backend/open_webui/utils/middleware.py index 0ff8d12e6a..e98dc0fa93 100644 --- a/backend/open_webui/utils/middleware.py +++ b/backend/open_webui/utils/middleware.py @@ -1645,7 +1645,18 @@ def add_file_context(messages: list, chat_id: str, user) -> list: attrs += f' name="{file["name"]}"' return f'' - for message, stored_message in zip(messages, stored_messages): + # Pair only user-role messages from both lists to avoid misalignment. + # After process_messages_with_output(), assistant messages with tool calls + # are expanded into multiple messages (assistant + tool results), making + # the payload message list longer than the stored message list. A naive + # positional zip() would pair user messages with wrong stored messages, + # causing later images to lose their file context (see #21878). + user_messages = [m for m in messages if m.get("role") == "user"] + stored_user_messages = [ + m for m in stored_messages if m.get("role") == "user" + ] + + for message, stored_message in zip(user_messages, stored_user_messages): files_with_urls = [ file for file in stored_message.get('files', [])