From 2b52b18faaf12b08b95710097a2e3a386d8b4d2d Mon Sep 17 00:00:00 2001 From: loulanyue <260355617@qq.com> Date: Sat, 1 Aug 2026 18:48:44 +0800 Subject: [PATCH] fix(oauth): normalize OAuth sub claim to str to prevent PostgreSQL type mismatch GitHub's /user API returns 'id' as a JSON number. When this numeric value reaches get_user_by_oauth_sub(), the PostgreSQL query User.oauth[provider].cast(JSONB)['sub'].astext == sub compares TEXT against INTEGER, raising: psycopg.errors.UndefinedFunction: operator does not exist: text = integer The SQLite path has the mirror-image problem: json_contains with an int sub never matches a record stored with a string sub, causing silent lookup misses. Fix: convert the extracted sub to str immediately after extraction, before it is stored in oauth_data or passed to any lookup/signup function. This is consistent with OIDC providers where 'sub' is already a string per RFC 7519. Closes #27760 --- backend/open_webui/utils/oauth.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/backend/open_webui/utils/oauth.py b/backend/open_webui/utils/oauth.py index 6a9d897752..f48992cd12 100644 --- a/backend/open_webui/utils/oauth.py +++ b/backend/open_webui/utils/oauth.py @@ -1834,6 +1834,10 @@ class OAuthManager: if not sub: log.warning(f'OAuth callback failed, sub is missing: {user_data}') raise HTTPException(400, detail=ERROR_MESSAGES.INVALID_CRED) + # Normalize to str: some providers (e.g. GitHub) return a numeric id. + # Without this, PostgreSQL fails with "operator does not exist: text = integer" + # and SQLite containment checks silently miss (int vs str mismatch). + sub = str(sub) oauth_data = {} oauth_data[provider] = {