From 67c51f9fc0d682fb2fe8203a58443f561cf7c31b Mon Sep 17 00:00:00 2001 From: Developer Date: Mon, 6 Jul 2026 17:35:19 +0000 Subject: [PATCH] Fix: user_id validation causes read timeout on slow Jellyfin MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The previous fix called client.users() unconditionally to validate the user_id, adding an extra HTTP round-trip before the build. On a slow Jellyfin connection this burned through the 10s timeout before the actual libraries() call. Restructured to try libraries(user_id) directly first. Only when that fails does the worker resolve the username via the users API. So: - Correctly configured user_id (internal hash): zero extra round-trips. - Username like 'admin': libraries() fails → users() resolves it → retry. 283 backend tests pass; ruff clean. --- .../workers/media_index_worker.py | 24 ++++++++++--------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/backend/src/media_library_viewer_api/workers/media_index_worker.py b/backend/src/media_library_viewer_api/workers/media_index_worker.py index 530191a..daffa83 100644 --- a/backend/src/media_library_viewer_api/workers/media_index_worker.py +++ b/backend/src/media_library_viewer_api/workers/media_index_worker.py @@ -114,27 +114,29 @@ def _resolve_jellyfin(service_id: str) -> tuple[Any, str]: raise RuntimeError("No Jellyfin users found and no user_id configured on the service") user_id = users[0]["Id"] else: - # The config field accepts either a Jellyfin internal user ID (a long - # hash) or a username (e.g. "admin"). Validate against the users API: - # if the configured value doesn't match any user's Id, try matching by - # Name, then fall back to the first user. - users = client.users() - valid_ids = {str(u.get("Id", "")) for u in users} - if user_id not in valid_ids: + # Try the configured user_id directly. It might be the internal + # Jellyfin Id (a long hash) — in that case libraries() succeeds + # without an extra users() round-trip. Only if it fails do we + # resolve it via the users API (the config field accepts usernames + # like 'admin' too, but Jellyfin's API rejects them on /Users/). + try: + client.libraries(user_id) + except Exception: + users = client.users() match = next((u for u in users if str(u.get("Name", "")) == user_id), None) if match: - user_id = match["Id"] + resolved = match["Id"] logger.info( "Resolved username '%s' to Jellyfin Id '%s'", - service.get("config", {}).get("user_id"), user_id, + resolved, ) + user_id = resolved elif users: user_id = users[0]["Id"] logger.warning( - "user_id '%s' not found; falling back to first user '%s'", + "user_id '%s' not found; falling back to first user", service.get("config", {}).get("user_id"), - user_id, ) return client, user_id