[GH-ISSUE #23953] issue: DATABASE_USER_ACTIVE_STATUS_UPDATE_INTERVAL must be set to 0 for open webui to start up after 0.9.0 #58791

Closed
opened 2026-05-05 23:58:29 -05:00 by GiteaMirror · 1 comment
Owner

Originally created by @Classic298 on GitHub (Apr 21, 2026).
Original GitHub issue: https://github.com/open-webui/open-webui/issues/23953

Bug Report

Describe the bug

get_current_user in backend/open_webui/utils/auth.py crashes with TypeError: a coroutine was expected, got None on every authenticated request after the first one within the DATABASE_USER_ACTIVE_STATUS_UPDATE_INTERVAL window. As a side effect, the except block deletes the user's auth cookies, silently logging them out.

Root Cause

Users.update_last_active_by_id (in backend/open_webui/models/users.py) is an async method decorated with @throttle(DATABASE_USER_ACTIVE_STATUS_UPDATE_INTERVAL).

The throttle decorator in backend/open_webui/utils/misc.py is a synchronous wrapper. When a call is throttled, it returns None instead of invoking the wrapped coroutine function. The caller in auth.py then does:

asyncio.create_task(Users.update_last_active_by_id(user.id))

Since the throttled call returns None (not a coroutine), asyncio.create_task(None) raises TypeError: a coroutine was expected, got None. The surrounding try/except catches this, raises further, and the outer handler deletes token, oauth_id_token, and oauth_session_id cookies — effectively logging the user out.

Steps to Reproduce

  1. Set DATABASE_USER_ACTIVE_STATUS_UPDATE_INTERVAL to any non-zero value (default 300).
  2. Log in as any user.
  3. Make two authenticated requests within the interval (e.g. reload the page).
  4. Second request crashes; user is logged out.

Expected Behavior

Throttled calls to the last_active_at update should be silently skipped without raising, and users should remain logged in.

Actual Behavior

File "/app/backend/open_webui/utils/auth.py", line 386, in get_current_user
    asyncio.create_task(Users.update_last_active_by_id(user.id))
  File "/usr/local/lib/python3.11/asyncio/tasks.py", line 384, in create_task
    task = loop.create_task(coro)
TypeError: a coroutine was expected, got None

Workaround

Set DATABASE_USER_ACTIVE_STATUS_UPDATE_INTERVAL=0 in the environment. This disables throttling (the decorator's now - last_call < 0 check is always false), so the async function is always invoked and always returns a coroutine. Downside: a DB UPDATE on every authenticated request.

Suggested Fix

Make the throttle decorator async-aware so it can wrap coroutine functions correctly — e.g. detect asyncio.iscoroutinefunction(func) and return either a no-op coroutine or an async def wrapper that awaits the real call. Alternatively, guard the call site in auth.py:

coro = Users.update_last_active_by_id(user.id)
if coro is not None:
    asyncio.create_task(coro)

but fixing the decorator is the cleaner solution since the same pattern could break elsewhere.

Relevant Files

  • backend/open_webui/utils/auth.py (line ~386)
  • backend/open_webui/models/users.py (line ~612, update_last_active_by_id)
  • backend/open_webui/utils/misc.py (line ~833, throttle)
Originally created by @Classic298 on GitHub (Apr 21, 2026). Original GitHub issue: https://github.com/open-webui/open-webui/issues/23953 ### Bug Report ### Describe the bug `get_current_user` in `backend/open_webui/utils/auth.py` crashes with `TypeError: a coroutine was expected, got None` on every authenticated request after the first one within the `DATABASE_USER_ACTIVE_STATUS_UPDATE_INTERVAL` window. As a side effect, the `except` block deletes the user's auth cookies, silently logging them out. ### Root Cause `Users.update_last_active_by_id` (in `backend/open_webui/models/users.py`) is an `async` method decorated with `@throttle(DATABASE_USER_ACTIVE_STATUS_UPDATE_INTERVAL)`. The `throttle` decorator in `backend/open_webui/utils/misc.py` is a **synchronous** wrapper. When a call is throttled, it returns `None` instead of invoking the wrapped coroutine function. The caller in `auth.py` then does: ```python asyncio.create_task(Users.update_last_active_by_id(user.id)) ``` Since the throttled call returns `None` (not a coroutine), `asyncio.create_task(None)` raises `TypeError: a coroutine was expected, got None`. The surrounding `try/except` catches this, raises further, and the outer handler deletes `token`, `oauth_id_token`, and `oauth_session_id` cookies — effectively logging the user out. ### Steps to Reproduce 1. Set `DATABASE_USER_ACTIVE_STATUS_UPDATE_INTERVAL` to any non-zero value (default `300`). 2. Log in as any user. 3. Make two authenticated requests within the interval (e.g. reload the page). 4. Second request crashes; user is logged out. ### Expected Behavior Throttled calls to the `last_active_at` update should be silently skipped without raising, and users should remain logged in. ### Actual Behavior ``` File "/app/backend/open_webui/utils/auth.py", line 386, in get_current_user asyncio.create_task(Users.update_last_active_by_id(user.id)) File "/usr/local/lib/python3.11/asyncio/tasks.py", line 384, in create_task task = loop.create_task(coro) TypeError: a coroutine was expected, got None ``` ### Workaround Set `DATABASE_USER_ACTIVE_STATUS_UPDATE_INTERVAL=0` in the environment. This disables throttling (the decorator's `now - last_call < 0` check is always false), so the async function is always invoked and always returns a coroutine. Downside: a DB `UPDATE` on every authenticated request. ### Suggested Fix Make the `throttle` decorator async-aware so it can wrap coroutine functions correctly — e.g. detect `asyncio.iscoroutinefunction(func)` and return either a no-op coroutine or an `async def` wrapper that awaits the real call. Alternatively, guard the call site in `auth.py`: ```python coro = Users.update_last_active_by_id(user.id) if coro is not None: asyncio.create_task(coro) ``` but fixing the decorator is the cleaner solution since the same pattern could break elsewhere. ### Relevant Files - `backend/open_webui/utils/auth.py` (line ~386) - `backend/open_webui/models/users.py` (line ~612, `update_last_active_by_id`) - `backend/open_webui/utils/misc.py` (line ~833, `throttle`)
Author
Owner

@tjbck commented on GitHub (Apr 24, 2026):

Likely addressed in dev.

<!-- gh-comment-id:4311437749 --> @tjbck commented on GitHub (Apr 24, 2026): Likely addressed in dev.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/open-webui#58791