[GH-ISSUE #17495] issue: The "Filter Function" is causing issues with the Notes and Gemma3 models. #18308

Closed
opened 2026-04-20 00:31:18 -05:00 by GiteaMirror · 3 comments
Owner

Originally created by @j820301 on GitHub (Sep 17, 2025).
Original GitHub issue: https://github.com/open-webui/open-webui/issues/17495

Check Existing Issues

  • I have searched for any existing and/or related issues.
  • I have searched for any existing and/or related discussions.
  • I am using the latest version of Open WebUI.

Installation Method

Docker

Open WebUI Version

0.6.28

Ollama Version (if applicable)

0.11.10

Operating System

Ubuntu

Browser (if applicable)

No response

Confirmation

  • I have read and followed all instructions in README.md.
  • I am using the latest version of both Open WebUI and Ollama.
  • I have included the browser console logs.
  • I have included the Docker container logs.
  • I have provided every relevant configuration, setting, and environment variable used in my setup.
  • I have clearly listed every relevant configuration, custom setting, environment variable, and command-line option that influences my setup (such as Docker Compose overrides, .env values, browser settings, authentication configurations, etc).
  • I have documented step-by-step reproduction instructions that are precise, sequential, and leave nothing to interpretation. My steps:
  • Start with the initial platform/version/OS and dependencies used,
  • Specify exact install/launch/configure commands,
  • List URLs visited, user input (incl. example values/emails/passwords if needed),
  • Describe all options and toggles enabled or changed,
  • Include any files or environmental changes,
  • Identify the expected and actual result at each stage,
  • Ensure any reasonably skilled user can follow and hit the same issue.

Expected Behavior

Added a filter function and verified its correct operation

Actual Behavior

First, thank you to all the developers who contributed to openwebui. I am not a professional developer, but I enjoy the functionality of openwebui, and the following issues occurred while trying out the filter function.
I implemented Filter Function v1 and encountered an error during notes editing, as shown in the log: "AttributeError: 'str' object has no attribute 'ge'".
I then modified my Filter Function to v2, but it subsequently produced another error: "'dict' object has no attribute 'encode'", consistently experiencing format-related issues.
All of these issues occurred while in notes editing mode

Furthermore, enabling the Filter also causes Gemma3 to fail to load images.
Disabling the Filter restores normal functionality for both notes and Gemma3’s image recognition, but I require the Filter’s functionality

Image

Steps to Reproduce

add filter funtion

v1

from pydantic import BaseModel
from typing import Optional


class Filter:
    # Valves: Configuration options for the filter
    class Valves(BaseModel):
        pass

    def __init__(self):
        # Initialize valves (optional configuration for the Filter)
        self.valves = self.Valves()

    def inlet(self, body: dict, __user__: Optional[dict] = None) -> dict:
        keywords_to_remove = [
            "tony",
            "tom",
            "alice",
            "hank"
        ]
        last_message = body["messages"][-1]["content"]
        for keyword in keywords_to_remove:
            last_message = last_message.replace(keyword, "")
        last_message = last_message.strip()
        body["messages"][-1]["content"] = last_message
        return body

    def stream(self, event: dict) -> dict:
        for choice in event.get("choices", []):
            delta = choice.get("delta", {})
            if "content" in delta:
                content = delta["content"]
                replacements = [
            "tony",
            "tom",
            "alice",
            "hank"
                ]
                for string_to_replace in replacements:
                    content = content.replace(string_to_replace, " ")
                delta["content"] = content
        return event

    def outlet(self, body: dict, __user__: Optional[dict] = None) -> dict:
        replacements = [
            "tony",
            "tom",
            "alice",
            "hank"
        ]
        for message in body["messages"]:
            content = message["content"]
            for string_to_replace in replacements:
                content = content.replace(string_to_replace, " ")
            message["content"] = content
        return body

To resolve the AttributeError: 'str' object has no attribute 'get' issue, I released version 2

from pydantic import BaseModel
from typing import Optional, Union
import json


class Filter:
    # Valves: Configuration options for the filter
    class Valves(BaseModel):
        pass

    def __init__(self):
        # Initialize valves (optional configuration for the Filter)
        self.valves = self.Valves()

    def inlet(self, body: Union[dict, str], __user__: Optional[dict] = None) -> dict:
        if isinstance(body, str):
            try:
                body = json.loads(body)
            except Exception:
                return {}

        keywords_to_remove = [
            "tony",
            "tom",
            "alice",
            "hank"
        ]

        if "messages" in body and body["messages"]:
            last_message = body["messages"][-1].get("content", "")
            for keyword in keywords_to_remove:
                last_message = last_message.replace(keyword, "")
            body["messages"][-1]["content"] = last_message.strip()

        return body

    def stream(self, event: Union[dict, str]) -> dict:
        if isinstance(event, str):
            try:
                event = json.loads(event)
            except Exception:
                return {"choices": []}

        for choice in event.get("choices", []):
            delta = choice.get("delta", {})
            if "content" in delta:
                content = delta["content"]
                replacements = [
            "tony",
            "tom",
            "alice",
            "hank"
                ]
                for string_to_replace in replacements:
                    content = content.replace(string_to_replace, " ")
                delta["content"] = content
        return event

    def outlet(self, body: Union[dict, str], __user__: Optional[dict] = None) -> dict:
        if isinstance(body, str):
            try:
                body = json.loads(body)
            except Exception:
                return {}

        replacements = [
            "tony",
            "tom",
            "alice",
            "hank"
        ]

        if "messages" in body:
            for message in body["messages"]:
                content = message.get("content", "")
                for string_to_replace in replacements:
                    content = content.replace(string_to_replace, " ")
                message["content"] = content

        return body

However, an AttributeError: 'dict' object has no attribute 'encode' has now occurred
enabling the Filter also causes Gemma3 to fail to load images.

Logs & Screenshots

filter v1 logs
mpletions HTTP/1.1" 200 Exception in ASGI application Exception Group Traceback (most recent call last): | File "/usr/local/lib/python3.11/site-packages/starlette/_utils.py", line 76, in collapse_excgroups | yield | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 178, in call | async with anyio.create_task_group() as task_group: | File "/usr/local/lib/python3.11/site-packages/anyio/_backends/_asyncio.py", line 772, in aexit | raise BaseExceptionGroup( | ExceptionGroup: unhandled errors in a TaskGroup (1 sub-exception) +-+---------------- 1 ---------------- | Traceback (most recent call last): | File "/usr/local/lib/python3.11/site-packages/uvicorn/protocols/http/httptools_impl.py", line 409, in run_asgi | result = await app( # type: ignore[func-returns-value] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | File "/usr/local/lib/python3.11/site-packages/uvicorn/middleware/proxy_headers.py", line 60, in call | return await self.app(scope, receive, send) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | File "/usr/local/lib/python3.11/site-packages/fastapi/applications.py", line 1054, in call | await super().call(scope, receive, send) | File "/usr/local/lib/python3.11/site-packages/starlette/applications.py", line 112, in call | await self.middleware_stack(scope, receive, send) | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/errors.py", line 187, in call | raise exc | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/errors.py", line 165, in call | await self.app(scope, receive, _send) | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/sessions.py", line 85, in call | await self.app(scope, receive, send_wrapper) | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/cors.py", line 93, in call | await self.simple_response(scope, receive, send, request_headers=headers) | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/cors.py", line 144, in simple_response | await self.app(scope, receive, send) | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 177, in call | with recv_stream, send_stream, collapse_excgroups(): | File "/usr/local/lib/python3.11/contextlib.py", line 158, in exit | self.gen.throw(typ, value, traceback) | File "/usr/local/lib/python3.11/site-packages/starlette/_utils.py", line 82, in collapse_excgroups | raise exc | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 180, in call | await response(scope, wrapped_receive, send) | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 215, in call | async for chunk in self.body_iterator: | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 169, in body_stream | raise app_exc | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 141, in coro | await self.app(scope, receive_or_disconnect, send_no_error) | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 177, in call | with recv_stream, send_stream, collapse_excgroups(): | File "/usr/local/lib/python3.11/contextlib.py", line 158, in exit | self.gen.throw(typ, value, traceback) | File "/usr/local/lib/python3.11/site-packages/starlette/_utils.py", line 82, in collapse_excgroups | raise exc | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 180, in call | await response(scope, wrapped_receive, send) | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 215, in call | async for chunk in self.body_iterator: | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 169, in body_stream | raise app_exc | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 141, in coro | await self.app(scope, receive_or_disconnect, send_no_error) | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 177, in call | with recv_stream, send_stream, collapse_excgroups(): | File "/usr/local/lib/python3.11/contextlib.py", line 158, in exit | self.gen.throw(typ, value, traceback) | File "/usr/local/lib/python3.11/site-packages/starlette/_utils.py", line 82, in collapse_excgroups | raise exc | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 180, in call | await response(scope, wrapped_receive, send) | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 215, in call | async for chunk in self.body_iterator: | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 169, in body_stream | raise app_exc | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 141, in coro | await self.app(scope, receive_or_disconnect, send_no_error) | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 177, in call | with recv_stream, send_stream, collapse_excgroups(): | File "/usr/local/lib/python3.11/contextlib.py", line 158, in exit | self.gen.throw(typ, value, traceback) | File "/usr/local/lib/python3.11/site-packages/starlette/_utils.py", line 82, in collapse_excgroups | raise exc | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 180, in call | await response(scope, wrapped_receive, send) | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 215, in call | async for chunk in self.body_iterator: | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 169, in body_stream | raise app_exc | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 141, in coro | await self.app(scope, receive_or_disconnect, send_no_error) | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 177, in call | with recv_stream, send_stream, collapse_excgroups(): | File "/usr/local/lib/python3.11/contextlib.py", line 158, in exit | self.gen.throw(typ, value, traceback) | File "/usr/local/lib/python3.11/site-packages/starlette/_utils.py", line 82, in collapse_excgroups | raise exc | File "/usr/local/lib/python3.11/site-packages/starlette/responses.py", line 264, in wrap | await func() | File "/usr/local/lib/python3.11/site-packages/starlette/responses.py", line 245, in stream_response | async for chunk in self.body_iterator: | File "/app/backend/open_webui/utils/middleware.py", line 2744, in stream_wrapper | data, _= await process_filter_functions( | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | File "/app/backend/open_webui/utils/filter.py", line 127, in process_filter_functions | raise e | File "/app/backend/open_webui/utils/filter.py", line 123, in process_filter_functions | form_data = handler(**params) | ^^^^^^^^^^^^^^^^^ | File "<string>", line 47, in stream | AttributeError: 'str' object has no attribute 'get' +------------------------------------ During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/usr/local/lib/python3.11/site-packages/uvicorn/protocols/http/httptools_impl.py", line 409, in run_asgi result = await app( # type: ignore[func-returns-value] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.11/site-packages/uvicorn/middleware/proxy_headers.py", line 60, in call return await self.app(scope, receive, send) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.11/site-packages/fastapi/applications.py", line 1054, in call await super().call(scope, receive, send) File "/usr/local/lib/python3.11/site-packages/starlette/applications.py", line 112, in call await self.middleware_stack(scope, receive, send) File "/usr/local/lib/python3.11/site-packages/starlette/middleware/errors.py", line 187, in call raise exc File "/usr/local/lib/python3.11/site-packages/starlette/middleware/errors.py", line 165, in call await self.app(scope, receive, _send) File "/usr/local/lib/python3.11/site-packages/starlette/middleware/sessions.py", line 85, in call await self.app(scope, receive, send_wrapper) File "/usr/local/lib/python3.11/site-packages/starlette/middleware/cors.py", line 93, in call await self.simple_response(scope, receive, send, request_headers=headers) File "/usr/local/lib/python3.11/site-packages/starlette/middleware/cors.py", line 144, in simple_response await self.app(scope, receive, send) File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 177, in call with recv_stream, send_stream, collapse_excgroups(): File "/usr/local/lib/python3.11/contextlib.py", line 158, in exit self.gen.throw(typ, value, traceback) File "/usr/local/lib/python3.11/site-packages/starlette/_utils.py", line 82, in collapse_excgroups raise exc File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 180, in call await response(scope, wrapped_receive, send) File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 215, in call async for chunk in self.body_iterator: File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 169, in body_stream raise app_exc File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 141, in coro await self.app(scope, receive_or_disconnect, send_no_error) File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 177, in call with recv_stream, send_stream, collapse_excgroups(): File "/usr/local/lib/python3.11/contextlib.py", line 158, in exit self.gen.throw(typ, value, traceback) File "/usr/local/lib/python3.11/site-packages/starlette/_utils.py", line 82, in collapse_excgroups raise exc File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 180, in call await response(scope, wrapped_receive, send) File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 215, in call async for chunk in self.body_iterator: File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 169, in body_stream raise app_exc File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 141, in coro await self.app(scope, receive_or_disconnect, send_no_error) File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 177, in call with recv_stream, send_stream, collapse_excgroups(): File "/usr/local/lib/python3.11/contextlib.py", line 158, in exit self.gen.throw(typ, value, traceback) File "/usr/local/lib/python3.11/site-packages/starlette/_utils.py", line 82, in collapse_excgroups raise exc File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 180, in call await response(scope, wrapped_receive, send) File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 215, in call async for chunk in self.body_iterator: File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 169, in body_stream raise app_exc File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 141, in coro await self.app(scope, receive_or_disconnect, send_no_error) File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 177, in call with recv_stream, send_stream, collapse_excgroups(): File "/usr/local/lib/python3.11/contextlib.py", line 158, in exit self.gen.throw(typ, value, traceback) File "/usr/local/lib/python3.11/site-packages/starlette/_utils.py", line 82, in collapse_excgroups raise exc File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 180, in call await response(scope, wrapped_receive, send) File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 215, in call async for chunk in self.body_iterator: File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 169, in body_stream raise app_exc File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 141, in coro await self.app(scope, receive_or_disconnect, send_no_error) File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 177, in call with recv_stream, send_stream, collapse_excgroups(): File "/usr/local/lib/python3.11/contextlib.py", line 158, in exit self.gen.throw(typ, value, traceback) File "/usr/local/lib/python3.11/site-packages/starlette/_utils.py", line 82, in collapse_excgroups raise exc File "/usr/local/lib/python3.11/site-packages/starlette/responses.py", line 264, in wrap await func() File "/usr/local/lib/python3.11/site-packages/starlette/responses.py", line 245, in stream_response async for chunk in self.body_iterator: File "/app/backend/open_webui/utils/middleware.py", line 2744, in stream_wrapper data, _= await process_filter_functions( ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/app/backend/open_webui/utils/filter.py", line 127, in process_filter_functions raise e File "/app/backend/open_webui/utils/filter.py", line 123, in process_filter_functions form_data = handler(**params) ^^^^^^^^^^^^^^^^^ File "<string>", line 47, in stream AttributeError: 'str' object has no attribute 'ge

filter v2 logs
Exception in ASGI application + Exception Group Traceback (most recent call last): | File "/usr/local/lib/python3.11/site-packages/starlette/_utils.py", line 76, in collapse_excgroups | yield | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 178, in __call__ | async with anyio.create_task_group() as task_group: | File "/usr/local/lib/python3.11/site-packages/anyio/_backends/_asyncio.py", line 772, in __aexit__ | raise BaseExceptionGroup( | ExceptionGroup: unhandled errors in a TaskGroup (1 sub-exception) +-+---------------- 1 ---------------- | Traceback (most recent call last): | File "/usr/local/lib/python3.11/site-packages/uvicorn/protocols/http/httptools_impl.py", line 409, in run_asgi | result = await app( # type: ignore[func-returns-value] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | File "/usr/local/lib/python3.11/site-packages/uvicorn/middleware/proxy_headers.py", line 60, in __call__ | return await self.app(scope, receive, send) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | File "/usr/local/lib/python3.11/site-packages/fastapi/applications.py", line 1054, in __call__ | await super().__call__(scope, receive, send) | File "/usr/local/lib/python3.11/site-packages/starlette/applications.py", line 112, in __call__ | await self.middleware_stack(scope, receive, send) | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/errors.py", line 187, in __call__ | raise exc | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/errors.py", line 165, in __call__ | await self.app(scope, receive, _send) | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/sessions.py", line 85, in __call__ | await self.app(scope, receive, send_wrapper) | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/cors.py", line 93, in __call__ | await self.simple_response(scope, receive, send, request_headers=headers) | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/cors.py", line 144, in simple_response | await self.app(scope, receive, send) | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 177, in __call__ | with recv_stream, send_stream, collapse_excgroups(): | File "/usr/local/lib/python3.11/contextlib.py", line 158, in __exit__ | self.gen.throw(typ, value, traceback) | File "/usr/local/lib/python3.11/site-packages/starlette/_utils.py", line 82, in collapse_excgroups | raise exc | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 180, in __call__ | await response(scope, wrapped_receive, send) | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 215, in __call__ | async for chunk in self.body_iterator: | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 169, in body_stream | raise app_exc | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 141, in coro | await self.app(scope, receive_or_disconnect, send_no_error) | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 177, in __call__ | with recv_stream, send_stream, collapse_excgroups(): | File "/usr/local/lib/python3.11/contextlib.py", line 158, in __exit__ | self.gen.throw(typ, value, traceback) | File "/usr/local/lib/python3.11/site-packages/starlette/_utils.py", line 82, in collapse_excgroups | raise exc | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 180, in __call__ | await response(scope, wrapped_receive, send) | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 215, in __call__ | async for chunk in self.body_iterator: | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 169, in body_stream | raise app_exc | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 141, in coro | await self.app(scope, receive_or_disconnect, send_no_error) | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 177, in __call__ | with recv_stream, send_stream, collapse_excgroups(): | File "/usr/local/lib/python3.11/contextlib.py", line 158, in __exit__ | self.gen.throw(typ, value, traceback) | File "/usr/local/lib/python3.11/site-packages/starlette/_utils.py", line 82, in collapse_excgroups | raise exc | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 180, in __call__ | await response(scope, wrapped_receive, send) | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 215, in __call__ | async for chunk in self.body_iterator: | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 169, in body_stream | raise app_exc | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 141, in coro | await self.app(scope, receive_or_disconnect, send_no_error) | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 177, in __call__ | with recv_stream, send_stream, collapse_excgroups(): | File "/usr/local/lib/python3.11/contextlib.py", line 158, in __exit__ | self.gen.throw(typ, value, traceback) | File "/usr/local/lib/python3.11/site-packages/starlette/_utils.py", line 82, in collapse_excgroups | raise exc | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 180, in __call__ | await response(scope, wrapped_receive, send) | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 215, in __call__ | async for chunk in self.body_iterator: | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 169, in body_stream | raise app_exc | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 141, in coro | await self.app(scope, receive_or_disconnect, send_no_error) | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 177, in __call__ | with recv_stream, send_stream, collapse_excgroups(): | File "/usr/local/lib/python3.11/contextlib.py", line 158, in __exit__ | self.gen.throw(typ, value, traceback) | File "/usr/local/lib/python3.11/site-packages/starlette/_utils.py", line 82, in collapse_excgroups | raise exc | File "/usr/local/lib/python3.11/site-packages/starlette/responses.py", line 264, in wrap | await func() | File "/usr/local/lib/python3.11/site-packages/starlette/responses.py", line 247, in stream_response | chunk = chunk.encode(self.charset) | ^^^^^^^^^^^^ | AttributeError: 'dict' object has no attribute 'encode' +------------------------------------ During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/usr/local/lib/python3.11/site-packages/uvicorn/protocols/http/httptools_impl.py", line 409, in run_asgi result = await app( # type: ignore[func-returns-value] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.11/site-packages/uvicorn/middleware/proxy_headers.py", line 60, in __call__ return await self.app(scope, receive, send) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.11/site-packages/fastapi/applications.py", line 1054, in __call__ await super().__call__(scope, receive, send) File "/usr/local/lib/python3.11/site-packages/starlette/applications.py", line 112, in __call__ await self.middleware_stack(scope, receive, send) File "/usr/local/lib/python3.11/site-packages/starlette/middleware/errors.py", line 187, in __call__ raise exc File "/usr/local/lib/python3.11/site-packages/starlette/middleware/errors.py", line 165, in __call__ await self.app(scope, receive, _send) File "/usr/local/lib/python3.11/site-packages/starlette/middleware/sessions.py", line 85, in __call__ await self.app(scope, receive, send_wrapper) File "/usr/local/lib/python3.11/site-packages/starlette/middleware/cors.py", line 93, in __call__ await self.simple_response(scope, receive, send, request_headers=headers) File "/usr/local/lib/python3.11/site-packages/starlette/middleware/cors.py", line 144, in simple_response await self.app(scope, receive, send) File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 177, in __call__ with recv_stream, send_stream, collapse_excgroups(): File "/usr/local/lib/python3.11/contextlib.py", line 158, in __exit__ self.gen.throw(typ, value, traceback) File "/usr/local/lib/python3.11/site-packages/starlette/_utils.py", line 82, in collapse_excgroups raise exc File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 180, in __call__ await response(scope, wrapped_receive, send) File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 215, in __call__ async for chunk in self.body_iterator: File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 169, in body_stream raise app_exc File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 141, in coro await self.app(scope, receive_or_disconnect, send_no_error) File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 177, in __call__ with recv_stream, send_stream, collapse_excgroups(): File "/usr/local/lib/python3.11/contextlib.py", line 158, in __exit__ self.gen.throw(typ, value, traceback) File "/usr/local/lib/python3.11/site-packages/starlette/_utils.py", line 82, in collapse_excgroups raise exc File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 180, in __call__ await response(scope, wrapped_receive, send) File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 215, in __call__ async for chunk in self.body_iterator: File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 169, in body_stream raise app_exc File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 141, in coro await self.app(scope, receive_or_disconnect, send_no_error) File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 177, in __call__ with recv_stream, send_stream, collapse_excgroups(): File "/usr/local/lib/python3.11/contextlib.py", line 158, in __exit__ self.gen.throw(typ, value, traceback) File "/usr/local/lib/python3.11/site-packages/starlette/_utils.py", line 82, in collapse_excgroups raise exc File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 180, in __call__ await response(scope, wrapped_receive, send) File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 215, in __call__ async for chunk in self.body_iterator: File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 169, in body_stream raise app_exc File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 141, in coro await self.app(scope, receive_or_disconnect, send_no_error) File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 177, in __call__ with recv_stream, send_stream, collapse_excgroups(): File "/usr/local/lib/python3.11/contextlib.py", line 158, in __exit__ self.gen.throw(typ, value, traceback) File "/usr/local/lib/python3.11/site-packages/starlette/_utils.py", line 82, in collapse_excgroups raise exc File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 180, in __call__ await response(scope, wrapped_receive, send) File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 215, in __call__ async for chunk in self.body_iterator: File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 169, in body_stream raise app_exc File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 141, in coro await self.app(scope, receive_or_disconnect, send_no_error) File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 177, in __call__ with recv_stream, send_stream, collapse_excgroups(): File "/usr/local/lib/python3.11/contextlib.py", line 158, in __exit__ self.gen.throw(typ, value, traceback) File "/usr/local/lib/python3.11/site-packages/starlette/_utils.py", line 82, in collapse_excgroups raise exc File "/usr/local/lib/python3.11/site-packages/starlette/responses.py", line 264, in wrap await func() File "/usr/local/lib/python3.11/site-packages/starlette/responses.py", line 247, in stream_response chunk = chunk.encode(self.charset) ^^^^^^^^^^^^ AttributeError: 'dict' object has no attribute 'encode' 2025-09-17 02:34:12.739 | INFO | uvicorn.protocols.http.httptools_impl:send:476 - 10.68.211.161:0 - "GET /api/v1/chats/72c5723c-0b16-43ab-ba54-1895c3c19fbe HTTP/1.1" 200 /usr/local/lib/python3.11/asyncio/mixins.py:16: RuntimeWarning: coroutine 'OAuthManager._refresh_token' was never awaited

gemm3 image
2025-09-17 03:01:11.739 | INFO     | uvicorn.protocols.http.httptools_impl:send:476 - 10.68.26.14:0 - "POST /api/v1/chats/d8db155d-d423-4709-81b4-b96bb97a6f5b HTTP/1.1" 200 2025-09-17 03:01:11.907 | INFO     | uvicorn.protocols.http.httptools_impl:send:476 - 10.68.26.14:0 - "GET /api/v1/chats/?page=1 HTTP/1.1" 200 2025-09-17 03:01:11.931 | INFO     | uvicorn.protocols.http.httptools_impl:send:476 - 10.68.26.14:0 - "GET /api/v1/folders/ HTTP/1.1" 200 2025-09-17 03:01:11.954 | INFO     | uvicorn.protocols.http.httptools_impl:send:476 - 10.68.26.14:0 - "GET /api/v1/folders/ HTTP/1.1" 200 2025-09-17 03:01:11.996 | INFO     | uvicorn.protocols.http.httptools_impl:send:476 - 10.68.26.14:0 - "POST /api/chat/completions HTTP/1.1" 200 2025-09-17 03:01:12.040 | INFO     | uvicorn.protocols.http.httptools_impl:send:476 - 10.68.26.14:0 - "GET /api/v1/chats/?page=1 HTTP/1.1" 200 2025-09-17 03:01:12.071 | INFO     | uvicorn.protocols.http.httptools_impl:send:476 - 10.68.26.14:0 - "GET /api/v1/folders/ HTTP/1.1" 200 2025-09-17 03:01:12.089 | INFO     | uvicorn.protocols.http.httptools_impl:send:476 - 10.68.26.14:0 - "GET /api/v1/folders/ HTTP/1.1" 200

Additional Information

No response

Originally created by @j820301 on GitHub (Sep 17, 2025). Original GitHub issue: https://github.com/open-webui/open-webui/issues/17495 ### Check Existing Issues - [x] I have searched for any existing and/or related issues. - [x] I have searched for any existing and/or related discussions. - [x] I am using the latest version of Open WebUI. ### Installation Method Docker ### Open WebUI Version 0.6.28 ### Ollama Version (if applicable) 0.11.10 ### Operating System Ubuntu ### Browser (if applicable) _No response_ ### Confirmation - [x] I have read and followed all instructions in `README.md`. - [x] I am using the latest version of **both** Open WebUI and Ollama. - [x] I have included the browser console logs. - [x] I have included the Docker container logs. - [x] I have **provided every relevant configuration, setting, and environment variable used in my setup.** - [x] I have clearly **listed every relevant configuration, custom setting, environment variable, and command-line option that influences my setup** (such as Docker Compose overrides, .env values, browser settings, authentication configurations, etc). - [x] I have documented **step-by-step reproduction instructions that are precise, sequential, and leave nothing to interpretation**. My steps: - Start with the initial platform/version/OS and dependencies used, - Specify exact install/launch/configure commands, - List URLs visited, user input (incl. example values/emails/passwords if needed), - Describe all options and toggles enabled or changed, - Include any files or environmental changes, - Identify the expected and actual result at each stage, - Ensure any reasonably skilled user can follow and hit the same issue. ### Expected Behavior Added a filter function and verified its correct operation ### Actual Behavior First, thank you to all the developers who contributed to openwebui. I am not a professional developer, but I enjoy the functionality of openwebui, and the following issues occurred while trying out the filter function. I implemented Filter Function v1 and encountered an error during notes editing, as shown in the log: "AttributeError: 'str' object has no attribute 'ge'". I then modified my Filter Function to v2, but it subsequently produced another error: "'dict' object has no attribute 'encode'", consistently experiencing format-related issues. All of these issues occurred while in notes editing mode Furthermore, enabling the Filter also causes Gemma3 to fail to load images. Disabling the Filter restores normal functionality for both notes and Gemma3’s image recognition, but I require the Filter’s functionality <img width="1023" height="283" alt="Image" src="https://github.com/user-attachments/assets/08cf708f-872e-466d-af26-2e0fc781b479" /> ### Steps to Reproduce add filter funtion v1 ``` from pydantic import BaseModel from typing import Optional class Filter: # Valves: Configuration options for the filter class Valves(BaseModel): pass def __init__(self): # Initialize valves (optional configuration for the Filter) self.valves = self.Valves() def inlet(self, body: dict, __user__: Optional[dict] = None) -> dict: keywords_to_remove = [ "tony", "tom", "alice", "hank" ] last_message = body["messages"][-1]["content"] for keyword in keywords_to_remove: last_message = last_message.replace(keyword, "") last_message = last_message.strip() body["messages"][-1]["content"] = last_message return body def stream(self, event: dict) -> dict: for choice in event.get("choices", []): delta = choice.get("delta", {}) if "content" in delta: content = delta["content"] replacements = [ "tony", "tom", "alice", "hank" ] for string_to_replace in replacements: content = content.replace(string_to_replace, " ") delta["content"] = content return event def outlet(self, body: dict, __user__: Optional[dict] = None) -> dict: replacements = [ "tony", "tom", "alice", "hank" ] for message in body["messages"]: content = message["content"] for string_to_replace in replacements: content = content.replace(string_to_replace, " ") message["content"] = content return body ``` To resolve the AttributeError: 'str' object has no attribute 'get' issue, I released version 2 ``` from pydantic import BaseModel from typing import Optional, Union import json class Filter: # Valves: Configuration options for the filter class Valves(BaseModel): pass def __init__(self): # Initialize valves (optional configuration for the Filter) self.valves = self.Valves() def inlet(self, body: Union[dict, str], __user__: Optional[dict] = None) -> dict: if isinstance(body, str): try: body = json.loads(body) except Exception: return {} keywords_to_remove = [ "tony", "tom", "alice", "hank" ] if "messages" in body and body["messages"]: last_message = body["messages"][-1].get("content", "") for keyword in keywords_to_remove: last_message = last_message.replace(keyword, "") body["messages"][-1]["content"] = last_message.strip() return body def stream(self, event: Union[dict, str]) -> dict: if isinstance(event, str): try: event = json.loads(event) except Exception: return {"choices": []} for choice in event.get("choices", []): delta = choice.get("delta", {}) if "content" in delta: content = delta["content"] replacements = [ "tony", "tom", "alice", "hank" ] for string_to_replace in replacements: content = content.replace(string_to_replace, " ") delta["content"] = content return event def outlet(self, body: Union[dict, str], __user__: Optional[dict] = None) -> dict: if isinstance(body, str): try: body = json.loads(body) except Exception: return {} replacements = [ "tony", "tom", "alice", "hank" ] if "messages" in body: for message in body["messages"]: content = message.get("content", "") for string_to_replace in replacements: content = content.replace(string_to_replace, " ") message["content"] = content return body ``` However, an AttributeError: 'dict' object has no attribute 'encode' has now occurred enabling the Filter also causes Gemma3 to fail to load images. ### Logs & Screenshots filter v1 logs `mpletions HTTP/1.1" 200 Exception in ASGI application Exception Group Traceback (most recent call last): | File "/usr/local/lib/python3.11/site-packages/starlette/_utils.py", line 76, in collapse_excgroups | yield | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 178, in call | async with anyio.create_task_group() as task_group: | File "/usr/local/lib/python3.11/site-packages/anyio/_backends/_asyncio.py", line 772, in aexit | raise BaseExceptionGroup( | ExceptionGroup: unhandled errors in a TaskGroup (1 sub-exception) +-+---------------- 1 ---------------- | Traceback (most recent call last): | File "/usr/local/lib/python3.11/site-packages/uvicorn/protocols/http/httptools_impl.py", line 409, in run_asgi | result = await app( # type: ignore[func-returns-value] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | File "/usr/local/lib/python3.11/site-packages/uvicorn/middleware/proxy_headers.py", line 60, in call | return await self.app(scope, receive, send) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | File "/usr/local/lib/python3.11/site-packages/fastapi/applications.py", line 1054, in call | await super().call(scope, receive, send) | File "/usr/local/lib/python3.11/site-packages/starlette/applications.py", line 112, in call | await self.middleware_stack(scope, receive, send) | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/errors.py", line 187, in call | raise exc | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/errors.py", line 165, in call | await self.app(scope, receive, _send) | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/sessions.py", line 85, in call | await self.app(scope, receive, send_wrapper) | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/cors.py", line 93, in call | await self.simple_response(scope, receive, send, request_headers=headers) | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/cors.py", line 144, in simple_response | await self.app(scope, receive, send) | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 177, in call | with recv_stream, send_stream, collapse_excgroups(): | File "/usr/local/lib/python3.11/contextlib.py", line 158, in exit | self.gen.throw(typ, value, traceback) | File "/usr/local/lib/python3.11/site-packages/starlette/_utils.py", line 82, in collapse_excgroups | raise exc | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 180, in call | await response(scope, wrapped_receive, send) | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 215, in call | async for chunk in self.body_iterator: | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 169, in body_stream | raise app_exc | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 141, in coro | await self.app(scope, receive_or_disconnect, send_no_error) | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 177, in call | with recv_stream, send_stream, collapse_excgroups(): | File "/usr/local/lib/python3.11/contextlib.py", line 158, in exit | self.gen.throw(typ, value, traceback) | File "/usr/local/lib/python3.11/site-packages/starlette/_utils.py", line 82, in collapse_excgroups | raise exc | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 180, in call | await response(scope, wrapped_receive, send) | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 215, in call | async for chunk in self.body_iterator: | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 169, in body_stream | raise app_exc | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 141, in coro | await self.app(scope, receive_or_disconnect, send_no_error) | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 177, in call | with recv_stream, send_stream, collapse_excgroups(): | File "/usr/local/lib/python3.11/contextlib.py", line 158, in exit | self.gen.throw(typ, value, traceback) | File "/usr/local/lib/python3.11/site-packages/starlette/_utils.py", line 82, in collapse_excgroups | raise exc | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 180, in call | await response(scope, wrapped_receive, send) | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 215, in call | async for chunk in self.body_iterator: | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 169, in body_stream | raise app_exc | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 141, in coro | await self.app(scope, receive_or_disconnect, send_no_error) | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 177, in call | with recv_stream, send_stream, collapse_excgroups(): | File "/usr/local/lib/python3.11/contextlib.py", line 158, in exit | self.gen.throw(typ, value, traceback) | File "/usr/local/lib/python3.11/site-packages/starlette/_utils.py", line 82, in collapse_excgroups | raise exc | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 180, in call | await response(scope, wrapped_receive, send) | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 215, in call | async for chunk in self.body_iterator: | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 169, in body_stream | raise app_exc | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 141, in coro | await self.app(scope, receive_or_disconnect, send_no_error) | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 177, in call | with recv_stream, send_stream, collapse_excgroups(): | File "/usr/local/lib/python3.11/contextlib.py", line 158, in exit | self.gen.throw(typ, value, traceback) | File "/usr/local/lib/python3.11/site-packages/starlette/_utils.py", line 82, in collapse_excgroups | raise exc | File "/usr/local/lib/python3.11/site-packages/starlette/responses.py", line 264, in wrap | await func() | File "/usr/local/lib/python3.11/site-packages/starlette/responses.py", line 245, in stream_response | async for chunk in self.body_iterator: | File "/app/backend/open_webui/utils/middleware.py", line 2744, in stream_wrapper | data, _= await process_filter_functions( | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | File "/app/backend/open_webui/utils/filter.py", line 127, in process_filter_functions | raise e | File "/app/backend/open_webui/utils/filter.py", line 123, in process_filter_functions | form_data = handler(**params) | ^^^^^^^^^^^^^^^^^ | File "<string>", line 47, in stream | AttributeError: 'str' object has no attribute 'get' +------------------------------------ During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/usr/local/lib/python3.11/site-packages/uvicorn/protocols/http/httptools_impl.py", line 409, in run_asgi result = await app( # type: ignore[func-returns-value] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.11/site-packages/uvicorn/middleware/proxy_headers.py", line 60, in call return await self.app(scope, receive, send) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.11/site-packages/fastapi/applications.py", line 1054, in call await super().call(scope, receive, send) File "/usr/local/lib/python3.11/site-packages/starlette/applications.py", line 112, in call await self.middleware_stack(scope, receive, send) File "/usr/local/lib/python3.11/site-packages/starlette/middleware/errors.py", line 187, in call raise exc File "/usr/local/lib/python3.11/site-packages/starlette/middleware/errors.py", line 165, in call await self.app(scope, receive, _send) File "/usr/local/lib/python3.11/site-packages/starlette/middleware/sessions.py", line 85, in call await self.app(scope, receive, send_wrapper) File "/usr/local/lib/python3.11/site-packages/starlette/middleware/cors.py", line 93, in call await self.simple_response(scope, receive, send, request_headers=headers) File "/usr/local/lib/python3.11/site-packages/starlette/middleware/cors.py", line 144, in simple_response await self.app(scope, receive, send) File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 177, in call with recv_stream, send_stream, collapse_excgroups(): File "/usr/local/lib/python3.11/contextlib.py", line 158, in exit self.gen.throw(typ, value, traceback) File "/usr/local/lib/python3.11/site-packages/starlette/_utils.py", line 82, in collapse_excgroups raise exc File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 180, in call await response(scope, wrapped_receive, send) File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 215, in call async for chunk in self.body_iterator: File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 169, in body_stream raise app_exc File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 141, in coro await self.app(scope, receive_or_disconnect, send_no_error) File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 177, in call with recv_stream, send_stream, collapse_excgroups(): File "/usr/local/lib/python3.11/contextlib.py", line 158, in exit self.gen.throw(typ, value, traceback) File "/usr/local/lib/python3.11/site-packages/starlette/_utils.py", line 82, in collapse_excgroups raise exc File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 180, in call await response(scope, wrapped_receive, send) File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 215, in call async for chunk in self.body_iterator: File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 169, in body_stream raise app_exc File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 141, in coro await self.app(scope, receive_or_disconnect, send_no_error) File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 177, in call with recv_stream, send_stream, collapse_excgroups(): File "/usr/local/lib/python3.11/contextlib.py", line 158, in exit self.gen.throw(typ, value, traceback) File "/usr/local/lib/python3.11/site-packages/starlette/_utils.py", line 82, in collapse_excgroups raise exc File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 180, in call await response(scope, wrapped_receive, send) File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 215, in call async for chunk in self.body_iterator: File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 169, in body_stream raise app_exc File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 141, in coro await self.app(scope, receive_or_disconnect, send_no_error) File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 177, in call with recv_stream, send_stream, collapse_excgroups(): File "/usr/local/lib/python3.11/contextlib.py", line 158, in exit self.gen.throw(typ, value, traceback) File "/usr/local/lib/python3.11/site-packages/starlette/_utils.py", line 82, in collapse_excgroups raise exc File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 180, in call await response(scope, wrapped_receive, send) File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 215, in call async for chunk in self.body_iterator: File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 169, in body_stream raise app_exc File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 141, in coro await self.app(scope, receive_or_disconnect, send_no_error) File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 177, in call with recv_stream, send_stream, collapse_excgroups(): File "/usr/local/lib/python3.11/contextlib.py", line 158, in exit self.gen.throw(typ, value, traceback) File "/usr/local/lib/python3.11/site-packages/starlette/_utils.py", line 82, in collapse_excgroups raise exc File "/usr/local/lib/python3.11/site-packages/starlette/responses.py", line 264, in wrap await func() File "/usr/local/lib/python3.11/site-packages/starlette/responses.py", line 245, in stream_response async for chunk in self.body_iterator: File "/app/backend/open_webui/utils/middleware.py", line 2744, in stream_wrapper data, _= await process_filter_functions( ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/app/backend/open_webui/utils/filter.py", line 127, in process_filter_functions raise e File "/app/backend/open_webui/utils/filter.py", line 123, in process_filter_functions form_data = handler(**params) ^^^^^^^^^^^^^^^^^ File "<string>", line 47, in stream AttributeError: 'str' object has no attribute 'ge` filter v2 logs `Exception in ASGI application + Exception Group Traceback (most recent call last): | File "/usr/local/lib/python3.11/site-packages/starlette/_utils.py", line 76, in collapse_excgroups | yield | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 178, in __call__ | async with anyio.create_task_group() as task_group: | File "/usr/local/lib/python3.11/site-packages/anyio/_backends/_asyncio.py", line 772, in __aexit__ | raise BaseExceptionGroup( | ExceptionGroup: unhandled errors in a TaskGroup (1 sub-exception) +-+---------------- 1 ---------------- | Traceback (most recent call last): | File "/usr/local/lib/python3.11/site-packages/uvicorn/protocols/http/httptools_impl.py", line 409, in run_asgi | result = await app( # type: ignore[func-returns-value] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | File "/usr/local/lib/python3.11/site-packages/uvicorn/middleware/proxy_headers.py", line 60, in __call__ | return await self.app(scope, receive, send) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | File "/usr/local/lib/python3.11/site-packages/fastapi/applications.py", line 1054, in __call__ | await super().__call__(scope, receive, send) | File "/usr/local/lib/python3.11/site-packages/starlette/applications.py", line 112, in __call__ | await self.middleware_stack(scope, receive, send) | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/errors.py", line 187, in __call__ | raise exc | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/errors.py", line 165, in __call__ | await self.app(scope, receive, _send) | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/sessions.py", line 85, in __call__ | await self.app(scope, receive, send_wrapper) | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/cors.py", line 93, in __call__ | await self.simple_response(scope, receive, send, request_headers=headers) | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/cors.py", line 144, in simple_response | await self.app(scope, receive, send) | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 177, in __call__ | with recv_stream, send_stream, collapse_excgroups(): | File "/usr/local/lib/python3.11/contextlib.py", line 158, in __exit__ | self.gen.throw(typ, value, traceback) | File "/usr/local/lib/python3.11/site-packages/starlette/_utils.py", line 82, in collapse_excgroups | raise exc | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 180, in __call__ | await response(scope, wrapped_receive, send) | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 215, in __call__ | async for chunk in self.body_iterator: | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 169, in body_stream | raise app_exc | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 141, in coro | await self.app(scope, receive_or_disconnect, send_no_error) | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 177, in __call__ | with recv_stream, send_stream, collapse_excgroups(): | File "/usr/local/lib/python3.11/contextlib.py", line 158, in __exit__ | self.gen.throw(typ, value, traceback) | File "/usr/local/lib/python3.11/site-packages/starlette/_utils.py", line 82, in collapse_excgroups | raise exc | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 180, in __call__ | await response(scope, wrapped_receive, send) | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 215, in __call__ | async for chunk in self.body_iterator: | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 169, in body_stream | raise app_exc | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 141, in coro | await self.app(scope, receive_or_disconnect, send_no_error) | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 177, in __call__ | with recv_stream, send_stream, collapse_excgroups(): | File "/usr/local/lib/python3.11/contextlib.py", line 158, in __exit__ | self.gen.throw(typ, value, traceback) | File "/usr/local/lib/python3.11/site-packages/starlette/_utils.py", line 82, in collapse_excgroups | raise exc | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 180, in __call__ | await response(scope, wrapped_receive, send) | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 215, in __call__ | async for chunk in self.body_iterator: | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 169, in body_stream | raise app_exc | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 141, in coro | await self.app(scope, receive_or_disconnect, send_no_error) | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 177, in __call__ | with recv_stream, send_stream, collapse_excgroups(): | File "/usr/local/lib/python3.11/contextlib.py", line 158, in __exit__ | self.gen.throw(typ, value, traceback) | File "/usr/local/lib/python3.11/site-packages/starlette/_utils.py", line 82, in collapse_excgroups | raise exc | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 180, in __call__ | await response(scope, wrapped_receive, send) | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 215, in __call__ | async for chunk in self.body_iterator: | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 169, in body_stream | raise app_exc | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 141, in coro | await self.app(scope, receive_or_disconnect, send_no_error) | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 177, in __call__ | with recv_stream, send_stream, collapse_excgroups(): | File "/usr/local/lib/python3.11/contextlib.py", line 158, in __exit__ | self.gen.throw(typ, value, traceback) | File "/usr/local/lib/python3.11/site-packages/starlette/_utils.py", line 82, in collapse_excgroups | raise exc | File "/usr/local/lib/python3.11/site-packages/starlette/responses.py", line 264, in wrap | await func() | File "/usr/local/lib/python3.11/site-packages/starlette/responses.py", line 247, in stream_response | chunk = chunk.encode(self.charset) | ^^^^^^^^^^^^ | AttributeError: 'dict' object has no attribute 'encode' +------------------------------------ During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/usr/local/lib/python3.11/site-packages/uvicorn/protocols/http/httptools_impl.py", line 409, in run_asgi result = await app( # type: ignore[func-returns-value] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.11/site-packages/uvicorn/middleware/proxy_headers.py", line 60, in __call__ return await self.app(scope, receive, send) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.11/site-packages/fastapi/applications.py", line 1054, in __call__ await super().__call__(scope, receive, send) File "/usr/local/lib/python3.11/site-packages/starlette/applications.py", line 112, in __call__ await self.middleware_stack(scope, receive, send) File "/usr/local/lib/python3.11/site-packages/starlette/middleware/errors.py", line 187, in __call__ raise exc File "/usr/local/lib/python3.11/site-packages/starlette/middleware/errors.py", line 165, in __call__ await self.app(scope, receive, _send) File "/usr/local/lib/python3.11/site-packages/starlette/middleware/sessions.py", line 85, in __call__ await self.app(scope, receive, send_wrapper) File "/usr/local/lib/python3.11/site-packages/starlette/middleware/cors.py", line 93, in __call__ await self.simple_response(scope, receive, send, request_headers=headers) File "/usr/local/lib/python3.11/site-packages/starlette/middleware/cors.py", line 144, in simple_response await self.app(scope, receive, send) File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 177, in __call__ with recv_stream, send_stream, collapse_excgroups(): File "/usr/local/lib/python3.11/contextlib.py", line 158, in __exit__ self.gen.throw(typ, value, traceback) File "/usr/local/lib/python3.11/site-packages/starlette/_utils.py", line 82, in collapse_excgroups raise exc File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 180, in __call__ await response(scope, wrapped_receive, send) File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 215, in __call__ async for chunk in self.body_iterator: File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 169, in body_stream raise app_exc File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 141, in coro await self.app(scope, receive_or_disconnect, send_no_error) File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 177, in __call__ with recv_stream, send_stream, collapse_excgroups(): File "/usr/local/lib/python3.11/contextlib.py", line 158, in __exit__ self.gen.throw(typ, value, traceback) File "/usr/local/lib/python3.11/site-packages/starlette/_utils.py", line 82, in collapse_excgroups raise exc File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 180, in __call__ await response(scope, wrapped_receive, send) File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 215, in __call__ async for chunk in self.body_iterator: File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 169, in body_stream raise app_exc File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 141, in coro await self.app(scope, receive_or_disconnect, send_no_error) File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 177, in __call__ with recv_stream, send_stream, collapse_excgroups(): File "/usr/local/lib/python3.11/contextlib.py", line 158, in __exit__ self.gen.throw(typ, value, traceback) File "/usr/local/lib/python3.11/site-packages/starlette/_utils.py", line 82, in collapse_excgroups raise exc File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 180, in __call__ await response(scope, wrapped_receive, send) File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 215, in __call__ async for chunk in self.body_iterator: File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 169, in body_stream raise app_exc File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 141, in coro await self.app(scope, receive_or_disconnect, send_no_error) File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 177, in __call__ with recv_stream, send_stream, collapse_excgroups(): File "/usr/local/lib/python3.11/contextlib.py", line 158, in __exit__ self.gen.throw(typ, value, traceback) File "/usr/local/lib/python3.11/site-packages/starlette/_utils.py", line 82, in collapse_excgroups raise exc File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 180, in __call__ await response(scope, wrapped_receive, send) File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 215, in __call__ async for chunk in self.body_iterator: File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 169, in body_stream raise app_exc File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 141, in coro await self.app(scope, receive_or_disconnect, send_no_error) File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 177, in __call__ with recv_stream, send_stream, collapse_excgroups(): File "/usr/local/lib/python3.11/contextlib.py", line 158, in __exit__ self.gen.throw(typ, value, traceback) File "/usr/local/lib/python3.11/site-packages/starlette/_utils.py", line 82, in collapse_excgroups raise exc File "/usr/local/lib/python3.11/site-packages/starlette/responses.py", line 264, in wrap await func() File "/usr/local/lib/python3.11/site-packages/starlette/responses.py", line 247, in stream_response chunk = chunk.encode(self.charset) ^^^^^^^^^^^^ AttributeError: 'dict' object has no attribute 'encode' 2025-09-17 02:34:12.739 | INFO | uvicorn.protocols.http.httptools_impl:send:476 - 10.68.211.161:0 - "GET /api/v1/chats/72c5723c-0b16-43ab-ba54-1895c3c19fbe HTTP/1.1" 200 /usr/local/lib/python3.11/asyncio/mixins.py:16: RuntimeWarning: coroutine 'OAuthManager._refresh_token' was never awaited` gemm3 image `2025-09-17 03:01:11.739 | INFO     | uvicorn.protocols.http.httptools_impl:send:476 - 10.68.26.14:0 - "POST /api/v1/chats/d8db155d-d423-4709-81b4-b96bb97a6f5b HTTP/1.1" 200 2025-09-17 03:01:11.907 | INFO     | uvicorn.protocols.http.httptools_impl:send:476 - 10.68.26.14:0 - "GET /api/v1/chats/?page=1 HTTP/1.1" 200 2025-09-17 03:01:11.931 | INFO     | uvicorn.protocols.http.httptools_impl:send:476 - 10.68.26.14:0 - "GET /api/v1/folders/ HTTP/1.1" 200 2025-09-17 03:01:11.954 | INFO     | uvicorn.protocols.http.httptools_impl:send:476 - 10.68.26.14:0 - "GET /api/v1/folders/ HTTP/1.1" 200 2025-09-17 03:01:11.996 | INFO     | uvicorn.protocols.http.httptools_impl:send:476 - 10.68.26.14:0 - "POST /api/chat/completions HTTP/1.1" 200 2025-09-17 03:01:12.040 | INFO     | uvicorn.protocols.http.httptools_impl:send:476 - 10.68.26.14:0 - "GET /api/v1/chats/?page=1 HTTP/1.1" 200 2025-09-17 03:01:12.071 | INFO     | uvicorn.protocols.http.httptools_impl:send:476 - 10.68.26.14:0 - "GET /api/v1/folders/ HTTP/1.1" 200 2025-09-17 03:01:12.089 | INFO     | uvicorn.protocols.http.httptools_impl:send:476 - 10.68.26.14:0 - "GET /api/v1/folders/ HTTP/1.1" 200` ### Additional Information _No response_
GiteaMirror added the bug label 2026-04-20 00:31:19 -05:00
Author
Owner

@rgaricano commented on GitHub (Sep 17, 2025):

In first function it is assuming that content always is a string, if it isn't a string then fault when strip or replace.
In second function it create a dict of dict, then it fail when filter is processed in the streaming pipeline (it expect a dict.
Open WebUI's filter system has specific expectations:

  • inlet and outlet methods receive dict objects representing the request/response body
  • stream method receives dict objects representing individual streaming events

In first function it only need a str check and if it is then replace (similar as you did in second one: if isinstance(content, str):)

e.g. with valve for strings:

from pydantic import BaseModel, Field
from typing import Optional

class Filter:
    class Valves(BaseModel):
        priority: int = Field(
            default=0, description="Priority level for the filter operations."
        )
        keywords_to_remove: list = Field(
            default=["tony", "tom", "alice", "hank"], 
            description="Keywords to filter from messages"
        )

    def __init__(self):
        self.valves = self.Valves()

    def inlet(self, body: dict, __user__: Optional[dict] = None) -> dict:
        """Pre-process incoming chat requests"""
        if not body.get("messages"):
            return body

        last_message = body["messages"][-1]
        content = last_message.get("content", "")

        if isinstance(content, str):
            for keyword in self.valves.keywords_to_remove:
                content = content.replace(keyword, "")
            body["messages"][-1]["content"] = content.strip()

        return body

    def stream(self, event: dict) -> dict:
        """Process streaming response chunks"""
        for choice in event.get("choices", []):
            delta = choice.get("delta", {})
            if "content" in delta:
                content = delta["content"]
                if isinstance(content, str):
                    for keyword in self.valves.keywords_to_remove:
                        content = content.replace(keyword, " ")
                    delta["content"] = content
        return event

    def outlet(self, body: dict, __user__: Optional[dict] = None) -> dict:
        """Post-process complete responses"""
        if not body.get("messages"):
            return body

        for message in body["messages"]:
            content = message.get("content", "")
            if isinstance(content, str):
                for keyword in self.valves.keywords_to_remove:
                    content = content.replace(keyword, " ")
                message["content"] = content

        return body
<!-- gh-comment-id:3301789761 --> @rgaricano commented on GitHub (Sep 17, 2025): In first function it is assuming that content always is a string, if it isn't a string then fault when strip or replace. In second function it create a dict of dict, then it fail when filter is processed in the streaming pipeline (it expect a dict. Open WebUI's filter system has specific expectations: - inlet and outlet methods receive dict objects representing the request/response body - stream method receives dict objects representing individual streaming events In first function it only need a str check and if it is then replace (similar as you did in second one: `if isinstance(content, str):`) e.g. with valve for strings: ``` from pydantic import BaseModel, Field from typing import Optional class Filter: class Valves(BaseModel): priority: int = Field( default=0, description="Priority level for the filter operations." ) keywords_to_remove: list = Field( default=["tony", "tom", "alice", "hank"], description="Keywords to filter from messages" ) def __init__(self): self.valves = self.Valves() def inlet(self, body: dict, __user__: Optional[dict] = None) -> dict: """Pre-process incoming chat requests""" if not body.get("messages"): return body last_message = body["messages"][-1] content = last_message.get("content", "") if isinstance(content, str): for keyword in self.valves.keywords_to_remove: content = content.replace(keyword, "") body["messages"][-1]["content"] = content.strip() return body def stream(self, event: dict) -> dict: """Process streaming response chunks""" for choice in event.get("choices", []): delta = choice.get("delta", {}) if "content" in delta: content = delta["content"] if isinstance(content, str): for keyword in self.valves.keywords_to_remove: content = content.replace(keyword, " ") delta["content"] = content return event def outlet(self, body: dict, __user__: Optional[dict] = None) -> dict: """Post-process complete responses""" if not body.get("messages"): return body for message in body["messages"]: content = message.get("content", "") if isinstance(content, str): for keyword in self.valves.keywords_to_remove: content = content.replace(keyword, " ") message["content"] = content return body ```
Author
Owner

@j820301 commented on GitHub (Sep 17, 2025):

Thank you for your reply. I used your code and, after adding keywords, it can be filtered, but errors still occur when editing or generating in the Notes function.
Gemma3 can correctly identify images using your code.

logs
`2025-09-17 09:28:05.512 | INFO | uvicorn.protocols.http.httptools_impl:send:476 - 10.68.26.14:52985 - "POST /api/chat/completions HTTP/1.1" 200
Exception in ASGI application

  • Exception Group Traceback (most recent call last):
    | File "/usr/local/lib/python3.11/site-packages/starlette/_utils.py", line 76, in collapse_excgroups
    | yield
    | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 178, in call
    | async with anyio.create_task_group() as task_group:
    | File "/usr/local/lib/python3.11/site-packages/anyio/_backends/_asyncio.py", line 772, in aexit
    | raise BaseExceptionGroup(
    | ExceptionGroup: unhandled errors in a TaskGroup (1 sub-exception)
    +-+---------------- 1 ----------------
    | Traceback (most recent call last):
    | File "/usr/local/lib/python3.11/site-packages/uvicorn/protocols/http/httptools_impl.py", line 409, in run_asgi
    | result = await app( # type: ignore[func-returns-value]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    | File "/usr/local/lib/python3.11/site-packages/uvicorn/middleware/proxy_headers.py", line 60, in call
    | return await self.app(scope, receive, send)
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    | File "/usr/local/lib/python3.11/site-packages/fastapi/applications.py", line 1054, in call
    | await super().call(scope, receive, send)
    | File "/usr/local/lib/python3.11/site-packages/starlette/applications.py", line 112, in call
    | await self.middleware_stack(scope, receive, send)
    | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/errors.py", line 187, in call
    | raise exc
    | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/errors.py", line 165, in call
    | await self.app(scope, receive, _send)
    | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/cors.py", line 93, in call
    | await self.simple_response(scope, receive, send, request_headers=headers)
    | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/cors.py", line 144, in simple_response
    | await self.app(scope, receive, send)
    | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 177, in call
    | with recv_stream, send_stream, collapse_excgroups():
    | File "/usr/local/lib/python3.11/contextlib.py", line 158, in exit
    | self.gen.throw(typ, value, traceback)
    | File "/usr/local/lib/python3.11/site-packages/starlette/_utils.py", line 82, in collapse_excgroups
    | raise exc
    | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 180, in call
    | await response(scope, wrapped_receive, send)
    | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 215, in call
    | async for chunk in self.body_iterator:
    | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 169, in body_stream
    | raise app_exc
    | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 141, in coro
    | await self.app(scope, receive_or_disconnect, send_no_error)
    | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 177, in call
    | with recv_stream, send_stream, collapse_excgroups():
    | File "/usr/local/lib/python3.11/contextlib.py", line 158, in exit
    | self.gen.throw(typ, value, traceback)
    | File "/usr/local/lib/python3.11/site-packages/starlette/_utils.py", line 82, in collapse_excgroups
    | raise exc
    | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 180, in call
    | await response(scope, wrapped_receive, send)
    | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 215, in call
    | async for chunk in self.body_iterator:
    | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 169, in body_stream
    | raise app_exc
    | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 141, in coro
    | await self.app(scope, receive_or_disconnect, send_no_error)
    | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 177, in call
    | with recv_stream, send_stream, collapse_excgroups():
    | File "/usr/local/lib/python3.11/contextlib.py", line 158, in exit
    | self.gen.throw(typ, value, traceback)
    | File "/usr/local/lib/python3.11/site-packages/starlette/_utils.py", line 82, in collapse_excgroups
    | raise exc
    | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 180, in call
    | await response(scope, wrapped_receive, send)
    | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 215, in call
    | async for chunk in self.body_iterator:
    | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 169, in body_stream
    | raise app_exc
    | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 141, in coro
    | await self.app(scope, receive_or_disconnect, send_no_error)
    | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 177, in call
    | with recv_stream, send_stream, collapse_excgroups():
    | File "/usr/local/lib/python3.11/contextlib.py", line 158, in exit
    | self.gen.throw(typ, value, traceback)
    | File "/usr/local/lib/python3.11/site-packages/starlette/_utils.py", line 82, in collapse_excgroups
    | raise exc
    | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 180, in call
    | await response(scope, wrapped_receive, send)
    | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 215, in call
    | async for chunk in self.body_iterator:
    | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 169, in body_stream
    | raise app_exc
    | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 141, in coro
    | await self.app(scope, receive_or_disconnect, send_no_error)
    | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 177, in call
    | with recv_stream, send_stream, collapse_excgroups():
    | File "/usr/local/lib/python3.11/contextlib.py", line 158, in exit
    | self.gen.throw(typ, value, traceback)
    | File "/usr/local/lib/python3.11/site-packages/starlette/_utils.py", line 82, in collapse_excgroups
    | raise exc
    | File "/usr/local/lib/python3.11/site-packages/starlette/responses.py", line 264, in wrap
    | await func()
    | File "/usr/local/lib/python3.11/site-packages/starlette/responses.py", line 245, in stream_response
    | async for chunk in self.body_iterator:
    | File "/app/backend/open_webui/utils/middleware.py", line 2744, in stream_wrapper
    | data, _ = await process_filter_functions(
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    | File "/app/backend/open_webui/utils/filter.py", line 127, in process_filter_functions
    | raise e
    | File "/app/backend/open_webui/utils/filter.py", line 123, in process_filter_functions
    | form_data = handler(**params)
    | ^^^^^^^^^^^^^^^^^
    | File "", line 35, in stream
    | AttributeError: 'str' object has no attribute 'get'
    +------------------------------------

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/usr/local/lib/python3.11/site-packages/uvicorn/protocols/http/httptools_impl.py", line 409, in run_asgi
result = await app( # type: ignore[func-returns-value]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/uvicorn/middleware/proxy_headers.py", line 60, in call
return await self.app(scope, receive, send)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/fastapi/applications.py", line 1054, in call
await super().call(scope, receive, send)
File "/usr/local/lib/python3.11/site-packages/starlette/applications.py", line 112, in call
await self.middleware_stack(scope, receive, send)
File "/usr/local/lib/python3.11/site-packages/starlette/middleware/errors.py", line 187, in call
raise exc
File "/usr/local/lib/python3.11/site-packages/starlette/middleware/errors.py", line 165, in call
await self.app(scope, receive, _send)
File "/usr/local/lib/python3.11/site-packages/starlette/middleware/cors.py", line 93, in call
await self.simple_response(scope, receive, send, request_headers=headers)
File "/usr/local/lib/python3.11/site-packages/starlette/middleware/cors.py", line 144, in simple_response
await self.app(scope, receive, send)
File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 177, in call
with recv_stream, send_stream, collapse_excgroups():
File "/usr/local/lib/python3.11/contextlib.py", line 158, in exit
self.gen.throw(typ, value, traceback)
File "/usr/local/lib/python3.11/site-packages/starlette/_utils.py", line 82, in collapse_excgroups
raise exc
File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 180, in call
await response(scope, wrapped_receive, send)
File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 215, in call
async for chunk in self.body_iterator:
File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 169, in body_stream
raise app_exc
File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 141, in coro
await self.app(scope, receive_or_disconnect, send_no_error)
File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 177, in call
with recv_stream, send_stream, collapse_excgroups():
File "/usr/local/lib/python3.11/contextlib.py", line 158, in exit
self.gen.throw(typ, value, traceback)
File "/usr/local/lib/python3.11/site-packages/starlette/_utils.py", line 82, in collapse_excgroups
raise exc
File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 180, in call
await response(scope, wrapped_receive, send)
File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 215, in call
async for chunk in self.body_iterator:
File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 169, in body_stream
raise app_exc
File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 141, in coro
await self.app(scope, receive_or_disconnect, send_no_error)
File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 177, in call
with recv_stream, send_stream, collapse_excgroups():
File "/usr/local/lib/python3.11/contextlib.py", line 158, in exit
self.gen.throw(typ, value, traceback)
File "/usr/local/lib/python3.11/site-packages/starlette/_utils.py", line 82, in collapse_excgroups
raise exc
File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 180, in call
await response(scope, wrapped_receive, send)
File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 215, in call
async for chunk in self.body_iterator:
File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 169, in body_stream
raise app_exc
File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 141, in coro
await self.app(scope, receive_or_disconnect, send_no_error)
File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 177, in call
with recv_stream, send_stream, collapse_excgroups():
File "/usr/local/lib/python3.11/contextlib.py", line 158, in exit
self.gen.throw(typ, value, traceback)
File "/usr/local/lib/python3.11/site-packages/starlette/_utils.py", line 82, in collapse_excgroups
raise exc
File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 180, in call
await response(scope, wrapped_receive, send)
File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 215, in call
async for chunk in self.body_iterator:
File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 169, in body_stream
raise app_exc
File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 141, in coro
await self.app(scope, receive_or_disconnect, send_no_error)
File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 177, in call
with recv_stream, send_stream, collapse_excgroups():
File "/usr/local/lib/python3.11/contextlib.py", line 158, in exit
self.gen.throw(typ, value, traceback)
File "/usr/local/lib/python3.11/site-packages/starlette/_utils.py", line 82, in collapse_excgroups
raise exc
File "/usr/local/lib/python3.11/site-packages/starlette/responses.py", line 264, in wrap
await func()
File "/usr/local/lib/python3.11/site-packages/starlette/responses.py", line 245, in stream_response
async for chunk in self.body_iterator:
File "/app/backend/open_webui/utils/middleware.py", line 2744, in stream_wrapper
data, _ = await process_filter_functions(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/app/backend/open_webui/utils/filter.py", line 127, in process_filter_functions
raise e
File "/app/backend/open_webui/utils/filter.py", line 123, in process_filter_functions
form_data = handler(**params)
^^^^^^^^^^^^^^^^^
File "", line 35, in stream
AttributeError: 'str' object has no attribute 'get'
2025-09-17 09:28:20.303 | INFO | uvicorn.protocols.http.httptools_impl:send:476 - 10.68.26.14:53009 - "GET /_app/version.json HTTP/1.1" 200
2025-09-17 09:29:19.519 | INFO | uvicorn.protocols.http.httptools_impl:send:476 - 10.68.26.14:53065 - "GET /api/v1/chats/c00ae4f1-de2f-41ef-85cc-57a15af47e2d HTTP/1.1" 200
2025-09-17 09:29:19.558 | INFO | uvicorn.protocols.http.httptools_impl:send:476 - 10.68.26.14:53066 - "GET /api/v1/chats/c00ae4f1-de2f-41ef-85cc-57a15af47e2d HTTP/1.1" 200
2025-09-17 09:29:19.683 | ERROR | aiohttp.client:del:459 - Unclosed client session
client_session: <aiohttp.client.ClientSession object at 0x7ed77dd70090>
2025-09-17 09:29:19.695 | INFO | uvicorn.protocols.http.httptools_impl:send:476 - 10.68.26.14:53066 - "GET /api/v1/chats/8476383c-5442-4117-b69c-be3d826ed550 HTTP/1.1" 200
2025-09-17 09:29:19.894 | INFO | uvicorn.protocols.http.httptools_impl:send:476 - 10.68.26.14:53065 - "GET /api/v1/chats/339920b2-b808-4e09-8285-907ec53b50a6 HTTP/1.1" 200
2025-09-17 09:29:20.330 | INFO | uvicorn.protocols.http.httptools_impl:send:476 - 10.68.26.14:53067 - "GET /api/usage HTTP/1.1" 200
2025-09-17 09:29:20.350 | INFO | uvicorn.protocols.http.httptools_impl:send:476 - 10.68.26.14:53065 - "GET /_app/version.json HTTP/1.1" 200
2025-09-17 09:29:21.454 | INFO | open_webui.socket.main:yjs_document_leave:577 - User 480f230d-79b2-49e2-87ff-6c247a8f6f80 leaving document note:cd017d12-220b-41f5-a53c-307dfe5465fa
2025-09-17 09:29:21.454 | INFO | open_webui.socket.main:yjs_document_leave:596 - Cleaning up document note:cd017d12-220b-41f5-a53c-307dfe5465fa as no users are left
2025-09-17 09:29:21.504 | INFO | uvicorn.protocols.http.httptools_impl:send:476 - 10.68.26.14:53066 - "GET /api/v1/chats/afcf9082-d6b5-4428-a6dc-e538aafe3f57 HTTP/1.1" 200
2025-09-17 09:29:21.785 | INFO | uvicorn.protocols.http.httptools_impl:send:476 - 10.68.26.14:53066 - "GET /api/v1/users/?page=1&order_by=created_at&direction=asc HTTP/1.1" 200
2025-09-17 09:29:21.822 | INFO | uvicorn.protocols.http.httptools_impl:send:476 - 10.68.26.14:53065 - "GET /api/v1/users/?page=1&order_by=created_at&direction=asc HTTP/1.1" 200
2025-09-17 09:29:21.833 | INFO | uvicorn.protocols.http.httptools_impl:send:476 - 10.68.26.14:53067 - "GET /api/v1/chats/c16dac08-ce38-4d37-8599-a9a3f0d422a0 HTTP/1.1" 200
2025-09-17 09:29:21.855 | INFO | uvicorn.protocols.http.httptools_impl:send:476 - 10.68.26.14:53068 - "GET /api/v1/chats/5d893e4d-e77a-44d7-961f-eff5062b93fe HTTP/1.1" 200
2025-09-17 09:29:21.993 | INFO | uvicorn.protocols.http.httptools_impl:send:476 - 10.68.26.14:53067 - "GET /api/v1/users/?page=1&order_by=created_at&direction=asc HTTP/1.1" 200
2025-09-17 09:29:22.128 | INFO | uvicorn.protocols.http.httptools_impl:send:476 - 10.68.26.14:53069 - "GET /api/v1/users/?page=1&order_by=created_at&direction=asc HTTP/1.1" 200
2025-09-17 09:29:23.008 | INFO | uvicorn.protocols.http.httptools_impl:send:476 - 10.68.26.14:53066 - "GET /api/v1/auths/admin/config HTTP/1.1" 200
2025-09-17 09:29:23.045 | INFO | uvicorn.protocols.http.httptools_impl:send:476 - 10.68.26.14:53070 - "GET /api/webhook HTTP/1.1" 200
2025-09-17 09:29:23.074 | INFO | uvicorn.protocols.http.httptools_impl:send:476 - 10.68.26.14:53068 - "GET /api/version/updates HTTP/1.1" 200
2025-09-17 09:29:23.211 | INFO | uvicorn.protocols.http.httptools_impl:send:476 - 10.68.26.14:53066 - "GET /api/v1/auths/admin/config/ldap/server HTTP/1.1" 200
2025-09-17 09:29:23.262 | INFO | uvicorn.protocols.http.httptools_impl:send:476 - 10.68.26.14:53070 - "GET /api/v1/auths/admin/config HTTP/1.1" 200
2025-09-17 09:29:23.267 | INFO | uvicorn.protocols.http.httptools_impl:send:476 - 10.68.26.14:53068 - "GET /api/webhook HTTP/1.1" 200
2025-09-17 09:29:23.436 | INFO | uvicorn.protocols.http.httptools_impl:send:476 - 10.68.26.14:53070 - "GET /api/v1/auths/admin/config/ldap/server HTTP/1.1" 200
2025-09-17 09:29:23.441 | INFO | uvicorn.protocols.http.httptools_impl:send:476 - 10.68.26.14:53068 - "GET /ollama/config HTTP/1.1" 200
2025-09-17 09:29:23.547 | INFO | uvicorn.protocols.http.httptools_impl:send:476 - 10.68.26.14:53066 - "GET /api/version/updates HTTP/1.1" 200
2025-09-17 09:29:23.552 | INFO | uvicorn.protocols.http.httptools_impl:send:476 - 10.68.26.14:53070 - "GET /openai/config HTTP/1.1" 200
2025-09-17 09:29:23.588 | INFO | uvicorn.protocols.http.httptools_impl:send:476 - 10.68.26.14:53068 - "GET /api/v1/configs/connections HTTP/1.1" 200
2025-09-17 09:29:23.768 | INFO | uvicorn.protocols.http.httptools_impl:send:476 - 10.68.26.14:53066 - "GET /api/v1/auths/admin/config/ldap HTTP/1.1" 200
2025-09-17 09:29:23.978 | INFO | uvicorn.protocols.http.httptools_impl:send:476 - 10.68.26.14:53068 - "GET /api/v1/auths/admin/config/ldap HTTP/1.1" 200
2025-09-17 09:30:20.412 | INFO | uvicorn.protocols.http.httptools_impl:send:476 - 10.68.26.14:53126 - "GET /_app/version.json HTTP/1.1" 200`

<!-- gh-comment-id:3302144902 --> @j820301 commented on GitHub (Sep 17, 2025): Thank you for your reply. I used your code and, after adding keywords, it can be filtered, but errors still occur when editing or generating in the Notes function. Gemma3 can correctly identify images using your code. logs `2025-09-17 09:28:05.512 | INFO | uvicorn.protocols.http.httptools_impl:send:476 - 10.68.26.14:52985 - "POST /api/chat/completions HTTP/1.1" 200 Exception in ASGI application + Exception Group Traceback (most recent call last): | File "/usr/local/lib/python3.11/site-packages/starlette/_utils.py", line 76, in collapse_excgroups | yield | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 178, in __call__ | async with anyio.create_task_group() as task_group: | File "/usr/local/lib/python3.11/site-packages/anyio/_backends/_asyncio.py", line 772, in __aexit__ | raise BaseExceptionGroup( | ExceptionGroup: unhandled errors in a TaskGroup (1 sub-exception) +-+---------------- 1 ---------------- | Traceback (most recent call last): | File "/usr/local/lib/python3.11/site-packages/uvicorn/protocols/http/httptools_impl.py", line 409, in run_asgi | result = await app( # type: ignore[func-returns-value] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | File "/usr/local/lib/python3.11/site-packages/uvicorn/middleware/proxy_headers.py", line 60, in __call__ | return await self.app(scope, receive, send) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | File "/usr/local/lib/python3.11/site-packages/fastapi/applications.py", line 1054, in __call__ | await super().__call__(scope, receive, send) | File "/usr/local/lib/python3.11/site-packages/starlette/applications.py", line 112, in __call__ | await self.middleware_stack(scope, receive, send) | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/errors.py", line 187, in __call__ | raise exc | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/errors.py", line 165, in __call__ | await self.app(scope, receive, _send) | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/cors.py", line 93, in __call__ | await self.simple_response(scope, receive, send, request_headers=headers) | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/cors.py", line 144, in simple_response | await self.app(scope, receive, send) | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 177, in __call__ | with recv_stream, send_stream, collapse_excgroups(): | File "/usr/local/lib/python3.11/contextlib.py", line 158, in __exit__ | self.gen.throw(typ, value, traceback) | File "/usr/local/lib/python3.11/site-packages/starlette/_utils.py", line 82, in collapse_excgroups | raise exc | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 180, in __call__ | await response(scope, wrapped_receive, send) | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 215, in __call__ | async for chunk in self.body_iterator: | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 169, in body_stream | raise app_exc | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 141, in coro | await self.app(scope, receive_or_disconnect, send_no_error) | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 177, in __call__ | with recv_stream, send_stream, collapse_excgroups(): | File "/usr/local/lib/python3.11/contextlib.py", line 158, in __exit__ | self.gen.throw(typ, value, traceback) | File "/usr/local/lib/python3.11/site-packages/starlette/_utils.py", line 82, in collapse_excgroups | raise exc | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 180, in __call__ | await response(scope, wrapped_receive, send) | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 215, in __call__ | async for chunk in self.body_iterator: | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 169, in body_stream | raise app_exc | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 141, in coro | await self.app(scope, receive_or_disconnect, send_no_error) | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 177, in __call__ | with recv_stream, send_stream, collapse_excgroups(): | File "/usr/local/lib/python3.11/contextlib.py", line 158, in __exit__ | self.gen.throw(typ, value, traceback) | File "/usr/local/lib/python3.11/site-packages/starlette/_utils.py", line 82, in collapse_excgroups | raise exc | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 180, in __call__ | await response(scope, wrapped_receive, send) | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 215, in __call__ | async for chunk in self.body_iterator: | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 169, in body_stream | raise app_exc | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 141, in coro | await self.app(scope, receive_or_disconnect, send_no_error) | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 177, in __call__ | with recv_stream, send_stream, collapse_excgroups(): | File "/usr/local/lib/python3.11/contextlib.py", line 158, in __exit__ | self.gen.throw(typ, value, traceback) | File "/usr/local/lib/python3.11/site-packages/starlette/_utils.py", line 82, in collapse_excgroups | raise exc | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 180, in __call__ | await response(scope, wrapped_receive, send) | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 215, in __call__ | async for chunk in self.body_iterator: | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 169, in body_stream | raise app_exc | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 141, in coro | await self.app(scope, receive_or_disconnect, send_no_error) | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 177, in __call__ | with recv_stream, send_stream, collapse_excgroups(): | File "/usr/local/lib/python3.11/contextlib.py", line 158, in __exit__ | self.gen.throw(typ, value, traceback) | File "/usr/local/lib/python3.11/site-packages/starlette/_utils.py", line 82, in collapse_excgroups | raise exc | File "/usr/local/lib/python3.11/site-packages/starlette/responses.py", line 264, in wrap | await func() | File "/usr/local/lib/python3.11/site-packages/starlette/responses.py", line 245, in stream_response | async for chunk in self.body_iterator: | File "/app/backend/open_webui/utils/middleware.py", line 2744, in stream_wrapper | data, _ = await process_filter_functions( | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | File "/app/backend/open_webui/utils/filter.py", line 127, in process_filter_functions | raise e | File "/app/backend/open_webui/utils/filter.py", line 123, in process_filter_functions | form_data = handler(**params) | ^^^^^^^^^^^^^^^^^ | File "<string>", line 35, in stream | AttributeError: 'str' object has no attribute 'get' +------------------------------------ During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/usr/local/lib/python3.11/site-packages/uvicorn/protocols/http/httptools_impl.py", line 409, in run_asgi result = await app( # type: ignore[func-returns-value] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.11/site-packages/uvicorn/middleware/proxy_headers.py", line 60, in __call__ return await self.app(scope, receive, send) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.11/site-packages/fastapi/applications.py", line 1054, in __call__ await super().__call__(scope, receive, send) File "/usr/local/lib/python3.11/site-packages/starlette/applications.py", line 112, in __call__ await self.middleware_stack(scope, receive, send) File "/usr/local/lib/python3.11/site-packages/starlette/middleware/errors.py", line 187, in __call__ raise exc File "/usr/local/lib/python3.11/site-packages/starlette/middleware/errors.py", line 165, in __call__ await self.app(scope, receive, _send) File "/usr/local/lib/python3.11/site-packages/starlette/middleware/cors.py", line 93, in __call__ await self.simple_response(scope, receive, send, request_headers=headers) File "/usr/local/lib/python3.11/site-packages/starlette/middleware/cors.py", line 144, in simple_response await self.app(scope, receive, send) File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 177, in __call__ with recv_stream, send_stream, collapse_excgroups(): File "/usr/local/lib/python3.11/contextlib.py", line 158, in __exit__ self.gen.throw(typ, value, traceback) File "/usr/local/lib/python3.11/site-packages/starlette/_utils.py", line 82, in collapse_excgroups raise exc File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 180, in __call__ await response(scope, wrapped_receive, send) File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 215, in __call__ async for chunk in self.body_iterator: File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 169, in body_stream raise app_exc File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 141, in coro await self.app(scope, receive_or_disconnect, send_no_error) File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 177, in __call__ with recv_stream, send_stream, collapse_excgroups(): File "/usr/local/lib/python3.11/contextlib.py", line 158, in __exit__ self.gen.throw(typ, value, traceback) File "/usr/local/lib/python3.11/site-packages/starlette/_utils.py", line 82, in collapse_excgroups raise exc File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 180, in __call__ await response(scope, wrapped_receive, send) File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 215, in __call__ async for chunk in self.body_iterator: File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 169, in body_stream raise app_exc File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 141, in coro await self.app(scope, receive_or_disconnect, send_no_error) File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 177, in __call__ with recv_stream, send_stream, collapse_excgroups(): File "/usr/local/lib/python3.11/contextlib.py", line 158, in __exit__ self.gen.throw(typ, value, traceback) File "/usr/local/lib/python3.11/site-packages/starlette/_utils.py", line 82, in collapse_excgroups raise exc File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 180, in __call__ await response(scope, wrapped_receive, send) File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 215, in __call__ async for chunk in self.body_iterator: File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 169, in body_stream raise app_exc File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 141, in coro await self.app(scope, receive_or_disconnect, send_no_error) File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 177, in __call__ with recv_stream, send_stream, collapse_excgroups(): File "/usr/local/lib/python3.11/contextlib.py", line 158, in __exit__ self.gen.throw(typ, value, traceback) File "/usr/local/lib/python3.11/site-packages/starlette/_utils.py", line 82, in collapse_excgroups raise exc File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 180, in __call__ await response(scope, wrapped_receive, send) File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 215, in __call__ async for chunk in self.body_iterator: File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 169, in body_stream raise app_exc File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 141, in coro await self.app(scope, receive_or_disconnect, send_no_error) File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 177, in __call__ with recv_stream, send_stream, collapse_excgroups(): File "/usr/local/lib/python3.11/contextlib.py", line 158, in __exit__ self.gen.throw(typ, value, traceback) File "/usr/local/lib/python3.11/site-packages/starlette/_utils.py", line 82, in collapse_excgroups raise exc File "/usr/local/lib/python3.11/site-packages/starlette/responses.py", line 264, in wrap await func() File "/usr/local/lib/python3.11/site-packages/starlette/responses.py", line 245, in stream_response async for chunk in self.body_iterator: File "/app/backend/open_webui/utils/middleware.py", line 2744, in stream_wrapper data, _ = await process_filter_functions( ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/app/backend/open_webui/utils/filter.py", line 127, in process_filter_functions raise e File "/app/backend/open_webui/utils/filter.py", line 123, in process_filter_functions form_data = handler(**params) ^^^^^^^^^^^^^^^^^ File "<string>", line 35, in stream AttributeError: 'str' object has no attribute 'get' 2025-09-17 09:28:20.303 | INFO | uvicorn.protocols.http.httptools_impl:send:476 - 10.68.26.14:53009 - "GET /_app/version.json HTTP/1.1" 200 2025-09-17 09:29:19.519 | INFO | uvicorn.protocols.http.httptools_impl:send:476 - 10.68.26.14:53065 - "GET /api/v1/chats/c00ae4f1-de2f-41ef-85cc-57a15af47e2d HTTP/1.1" 200 2025-09-17 09:29:19.558 | INFO | uvicorn.protocols.http.httptools_impl:send:476 - 10.68.26.14:53066 - "GET /api/v1/chats/c00ae4f1-de2f-41ef-85cc-57a15af47e2d HTTP/1.1" 200 2025-09-17 09:29:19.683 | ERROR | aiohttp.client:__del__:459 - Unclosed client session client_session: <aiohttp.client.ClientSession object at 0x7ed77dd70090> 2025-09-17 09:29:19.695 | INFO | uvicorn.protocols.http.httptools_impl:send:476 - 10.68.26.14:53066 - "GET /api/v1/chats/8476383c-5442-4117-b69c-be3d826ed550 HTTP/1.1" 200 2025-09-17 09:29:19.894 | INFO | uvicorn.protocols.http.httptools_impl:send:476 - 10.68.26.14:53065 - "GET /api/v1/chats/339920b2-b808-4e09-8285-907ec53b50a6 HTTP/1.1" 200 2025-09-17 09:29:20.330 | INFO | uvicorn.protocols.http.httptools_impl:send:476 - 10.68.26.14:53067 - "GET /api/usage HTTP/1.1" 200 2025-09-17 09:29:20.350 | INFO | uvicorn.protocols.http.httptools_impl:send:476 - 10.68.26.14:53065 - "GET /_app/version.json HTTP/1.1" 200 2025-09-17 09:29:21.454 | INFO | open_webui.socket.main:yjs_document_leave:577 - User 480f230d-79b2-49e2-87ff-6c247a8f6f80 leaving document note:cd017d12-220b-41f5-a53c-307dfe5465fa 2025-09-17 09:29:21.454 | INFO | open_webui.socket.main:yjs_document_leave:596 - Cleaning up document note:cd017d12-220b-41f5-a53c-307dfe5465fa as no users are left 2025-09-17 09:29:21.504 | INFO | uvicorn.protocols.http.httptools_impl:send:476 - 10.68.26.14:53066 - "GET /api/v1/chats/afcf9082-d6b5-4428-a6dc-e538aafe3f57 HTTP/1.1" 200 2025-09-17 09:29:21.785 | INFO | uvicorn.protocols.http.httptools_impl:send:476 - 10.68.26.14:53066 - "GET /api/v1/users/?page=1&order_by=created_at&direction=asc HTTP/1.1" 200 2025-09-17 09:29:21.822 | INFO | uvicorn.protocols.http.httptools_impl:send:476 - 10.68.26.14:53065 - "GET /api/v1/users/?page=1&order_by=created_at&direction=asc HTTP/1.1" 200 2025-09-17 09:29:21.833 | INFO | uvicorn.protocols.http.httptools_impl:send:476 - 10.68.26.14:53067 - "GET /api/v1/chats/c16dac08-ce38-4d37-8599-a9a3f0d422a0 HTTP/1.1" 200 2025-09-17 09:29:21.855 | INFO | uvicorn.protocols.http.httptools_impl:send:476 - 10.68.26.14:53068 - "GET /api/v1/chats/5d893e4d-e77a-44d7-961f-eff5062b93fe HTTP/1.1" 200 2025-09-17 09:29:21.993 | INFO | uvicorn.protocols.http.httptools_impl:send:476 - 10.68.26.14:53067 - "GET /api/v1/users/?page=1&order_by=created_at&direction=asc HTTP/1.1" 200 2025-09-17 09:29:22.128 | INFO | uvicorn.protocols.http.httptools_impl:send:476 - 10.68.26.14:53069 - "GET /api/v1/users/?page=1&order_by=created_at&direction=asc HTTP/1.1" 200 2025-09-17 09:29:23.008 | INFO | uvicorn.protocols.http.httptools_impl:send:476 - 10.68.26.14:53066 - "GET /api/v1/auths/admin/config HTTP/1.1" 200 2025-09-17 09:29:23.045 | INFO | uvicorn.protocols.http.httptools_impl:send:476 - 10.68.26.14:53070 - "GET /api/webhook HTTP/1.1" 200 2025-09-17 09:29:23.074 | INFO | uvicorn.protocols.http.httptools_impl:send:476 - 10.68.26.14:53068 - "GET /api/version/updates HTTP/1.1" 200 2025-09-17 09:29:23.211 | INFO | uvicorn.protocols.http.httptools_impl:send:476 - 10.68.26.14:53066 - "GET /api/v1/auths/admin/config/ldap/server HTTP/1.1" 200 2025-09-17 09:29:23.262 | INFO | uvicorn.protocols.http.httptools_impl:send:476 - 10.68.26.14:53070 - "GET /api/v1/auths/admin/config HTTP/1.1" 200 2025-09-17 09:29:23.267 | INFO | uvicorn.protocols.http.httptools_impl:send:476 - 10.68.26.14:53068 - "GET /api/webhook HTTP/1.1" 200 2025-09-17 09:29:23.436 | INFO | uvicorn.protocols.http.httptools_impl:send:476 - 10.68.26.14:53070 - "GET /api/v1/auths/admin/config/ldap/server HTTP/1.1" 200 2025-09-17 09:29:23.441 | INFO | uvicorn.protocols.http.httptools_impl:send:476 - 10.68.26.14:53068 - "GET /ollama/config HTTP/1.1" 200 2025-09-17 09:29:23.547 | INFO | uvicorn.protocols.http.httptools_impl:send:476 - 10.68.26.14:53066 - "GET /api/version/updates HTTP/1.1" 200 2025-09-17 09:29:23.552 | INFO | uvicorn.protocols.http.httptools_impl:send:476 - 10.68.26.14:53070 - "GET /openai/config HTTP/1.1" 200 2025-09-17 09:29:23.588 | INFO | uvicorn.protocols.http.httptools_impl:send:476 - 10.68.26.14:53068 - "GET /api/v1/configs/connections HTTP/1.1" 200 2025-09-17 09:29:23.768 | INFO | uvicorn.protocols.http.httptools_impl:send:476 - 10.68.26.14:53066 - "GET /api/v1/auths/admin/config/ldap HTTP/1.1" 200 2025-09-17 09:29:23.978 | INFO | uvicorn.protocols.http.httptools_impl:send:476 - 10.68.26.14:53068 - "GET /api/v1/auths/admin/config/ldap HTTP/1.1" 200 2025-09-17 09:30:20.412 | INFO | uvicorn.protocols.http.httptools_impl:send:476 - 10.68.26.14:53126 - "GET /_app/version.json HTTP/1.1" 200`
Author
Owner

@rgaricano commented on GitHub (Sep 17, 2025):

That it's because the Notes function processes streaming data differently than regular chat completions. In the Notes editor, streaming responses are parsed from Server-Sent Events (SSE) format , the data comes in as "data: {json}" format and gets processed line by line.

You can replace the stream method to handle both string and dict inputs:

def stream(self, event) -> dict:
    """Process streaming response chunks"""
    # Handle string input (raw SSE data)
    if isinstance(event, str):
        try:
            import json
            event = json.loads(event)
        except (json.JSONDecodeError, TypeError):
            return {"choices": []}

    # Ensure we have a dict to work with
    if not isinstance(event, dict):
        return {"choices": []}

    for choice in event.get("choices", []):
        delta = choice.get("delta", {})
        if "content" in delta:
            content = delta["content"]
            if isinstance(content, str):
                for keyword in self.valves.keywords_to_remove:
                    content = content.replace(keyword, " ")
                delta["content"] = content
    return event
<!-- gh-comment-id:3302502839 --> @rgaricano commented on GitHub (Sep 17, 2025): That it's because the Notes function processes streaming data differently than regular chat completions. In the Notes editor, streaming responses are parsed from Server-Sent Events (SSE) format , the data comes in as "data: {json}" format and gets processed line by line. You can replace the stream method to handle both string and dict inputs: ``` def stream(self, event) -> dict: """Process streaming response chunks""" # Handle string input (raw SSE data) if isinstance(event, str): try: import json event = json.loads(event) except (json.JSONDecodeError, TypeError): return {"choices": []} # Ensure we have a dict to work with if not isinstance(event, dict): return {"choices": []} for choice in event.get("choices", []): delta = choice.get("delta", {}) if "content" in delta: content = delta["content"] if isinstance(content, str): for keyword in self.valves.keywords_to_remove: content = content.replace(keyword, " ") delta["content"] = content return event ```
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/open-webui#18308