fix: handle chat_id=None in event emitter and Drive client

Two runtime regressions surfaced from server-to-server callers (tools,
automations, llm_council) hitting /api/chat/completions without a
chat_id, plus one missed await on the async OAuthSessions API.

1) socket/main.py get_event_emitter
   - request_info.get('chat_id', '').startswith(...) returned None when
     chat_id was explicitly None (dict.get default only applies when the
     key is missing entirely), causing 'NoneType' object has no attribute
     'startswith' and a 400 on every tool-driven completion request.
   - Use `(chat_id or '')` for both startswith calls.

2) utils/middleware.py background_tasks_handler
   - Same pattern: tightened the chat_id presence check from
     `'chat_id' in metadata` (False-positive on None values) to
     `metadata.get('chat_id')`. Also defensively switched two existing
     `metadata.get('chat_id', '').startswith(...)` checks to use the
     `or ''` pattern.

3) utils/google_drive_client.py create_drive_client_for_user
   - OAuthSessions.get_session_by_provider_and_user_id is now async
     (v0.9.5); the missing await produced
     "'coroutine' object has no attribute 'id'" when accessing
     .id on the returned coroutine and prevented all Drive sync runs.

Made-with: Cursor
This commit is contained in:
PVBLIC Foundation
2026-05-11 14:20:18 -07:00
parent c3ead772f1
commit 1cbfa1be06
3 changed files with 13 additions and 10 deletions
+6 -3
View File
@@ -898,8 +898,11 @@ async def _make_channel_emitter(request_info):
async def get_event_emitter(request_info, update_db=True):
# Channel mode: route pipeline output to channel message updates
if request_info.get('chat_id', '').startswith('channel:'):
# Channel mode: route pipeline output to channel message updates.
# Use `or ''` because callers may pass chat_id=None (server-to-server API
# callers like tools/automations); dict.get default only kicks in when
# the key is missing entirely.
if (request_info.get('chat_id') or '').startswith('channel:'):
return await _make_channel_emitter(request_info)
async def __event_emitter__(event_data):
@@ -917,7 +920,7 @@ async def get_event_emitter(request_info, update_db=True):
room=f'user:{user_id}',
)
if update_db and message_id and not request_info.get('chat_id', '').startswith('local:'):
if update_db and message_id and not (request_info.get('chat_id') or '').startswith('local:'):
event_type = event_data.get('type')
if event_type == 'status':
@@ -680,7 +680,7 @@ async def create_drive_client_for_user(
from open_webui.models.oauth_sessions import OAuthSessions
# Get Google OAuth session
oauth_session = OAuthSessions.get_session_by_provider_and_user_id("google", user_id)
oauth_session = await OAuthSessions.get_session_by_provider_and_user_id("google", user_id)
if not oauth_session:
log.warning(f"No Google OAuth session for user {user_id}")
return None
+6 -6
View File
@@ -3060,7 +3060,7 @@ async def background_tasks_handler(ctx):
messages = []
if (
'chat_id' in metadata
metadata.get('chat_id')
and not metadata['chat_id'].startswith('local:')
and not metadata['chat_id'].startswith('channel:')
):
@@ -3143,8 +3143,8 @@ async def background_tasks_handler(ctx):
}
)
if not metadata.get('chat_id', '').startswith('local:') and not metadata.get(
'chat_id', ''
if not (metadata.get('chat_id') or '').startswith('local:') and not (
metadata.get('chat_id') or ''
).startswith('channel:'):
await Chats.upsert_message_to_chat_by_id_and_message_id(
metadata['chat_id'],
@@ -3157,9 +3157,9 @@ async def background_tasks_handler(ctx):
except Exception as e:
pass
if not metadata.get('chat_id', '').startswith('local:') and not metadata.get('chat_id', '').startswith(
'channel:'
): # Only update titles and tags for non-temp chats
if not (metadata.get('chat_id') or '').startswith('local:') and not (
metadata.get('chat_id') or ''
).startswith('channel:'): # Only update titles and tags for non-temp chats
if TASKS.TITLE_GENERATION in tasks:
user_message = get_last_user_message(messages)
if user_message and len(user_message) > 100: