Skip to content

Fix Auto Memory async loop mismatch by avoiding detached event loop#8

Open
lukekenny wants to merge 1 commit into
Davixk:mainfrom
lukekenny:main
Open

Fix Auto Memory async loop mismatch by avoiding detached event loop#8
lukekenny wants to merge 1 commit into
Davixk:mainfrom
lukekenny:main

Conversation

@lukekenny
Copy link
Copy Markdown

Problem

When auto_memory() is launched via _run_detached() (new thread + new asyncio event loop), it later awaits Open WebUI async internals such as query_memory() / add_memory() / update_memory_by_id(). Those internals create Futures bound to the main uvicorn event loop. Awaiting them from a different loop causes Auto Memory to fail with:

got Future <Future pending> attached to a different loop

This is reproducible even with uvicorn workers set to 1, because it’s a loop/thread mismatch (not a multi-process issue).

Fix

  • Replace _run_detached(self.auto_memory(...)) with asyncio.create_task(self.auto_memory(...)) from inside the async outlet() function.
  • This keeps Auto Memory non-blocking (runs in the background) but ensures it runs on the same event loop as the request and Open WebUI internals.
  • (Optional / included if applicable) Make user["valves"] parsing robust: it’s commonly a dict, so parse via UserValves.model_validate(...) instead of requiring an already-instantiated Pydantic model.

How to reproduce

  • Install Auto Memory filter as-is.
  • Send a message that triggers memory creation (e.g. “Remember my first primary school was Sandringham Primary School”).
  • Observe failure in logs with the “Future attached to a different loop” error.

Expected result

Auto Memory should successfully query related memories and add/update/delete memories without event-loop errors.

Copy link
Copy Markdown
Owner

@Davixk Davixk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is only a problem with Redis enabled, as it modifies the event loop.
Redis is currently unsupported for Auto Memory, as noted in the readme document.

I believe Auto Memory should always be non-blocking, therefore I'm not willing to compromise this behavior for Redis support.

your proposal with asyncio.create_task(self.auto_memory(...)) does not achieve non-blocking behavior, as it will still block the request until the filter completes all coroutines.

the solution would be to detect when Redis is enabled, emit an explicit warning, and fall back to the blocking avenues, as I couldn't find any way to have non-blocking behavior when Redis was enabled, in my extensive testing a few months ago.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants