[GH-ISSUE #23669] Bug: OAuth session stores expires_at=None when token response omits expires_in, disabling refresh #58707

Closed
opened 2026-05-05 23:44:21 -05:00 by GiteaMirror · 2 comments
Owner

Originally created by @dhruvalgupta2003 on GitHub (Apr 13, 2026).
Original GitHub issue: https://github.com/open-webui/open-webui/issues/23669

Summary

On the OAuth callback, expires_at is derived from expires_in:

if 'expires_in' in token and 'expires_at' not in token:
    token['expires_at'] = datetime.now().timestamp() + token['expires_in']

If the token response lacks expires_in (some providers return only expires_at, or omit expiration entirely for certain grant types), expires_at is never populated. The session is then persisted with expires_at=None:

'expires_at': token.get('expires_at'),   # models/oauth_sessions.py:125

Impact

  • get_oauth_token cannot evaluate datetime.fromtimestamp(session.expires_at) when it's None, causing either a TypeError or a silent skip.
  • Tokens are never proactively refreshed. The next tool invocation after the token actually expires (unknown to us) fails with a 401 from the resource.

Location

  • backend/open_webui/utils/oauth.py ~ lines 881–882 (callback normalisation)
  • backend/open_webui/models/oauth_sessions.py ~ line 125 (persistence)
  • backend/open_webui/utils/oauth.py ~ line 706 (proactive-refresh check)

Suggested fix

  • If the provider returns expires_at directly, trust it.
  • If neither expires_in nor expires_at is present, either (a) fall back to a conservative default (e.g. 1 hour) and log a warning, or (b) always attempt a silent refresh before using the token, and surface a clear re-auth error if refresh fails.
  • Guard the expiry comparison against None so it never throws.
Originally created by @dhruvalgupta2003 on GitHub (Apr 13, 2026). Original GitHub issue: https://github.com/open-webui/open-webui/issues/23669 ### Summary On the OAuth callback, `expires_at` is derived from `expires_in`: ```python if 'expires_in' in token and 'expires_at' not in token: token['expires_at'] = datetime.now().timestamp() + token['expires_in'] ``` If the token response lacks `expires_in` (some providers return only `expires_at`, or omit expiration entirely for certain grant types), `expires_at` is never populated. The session is then persisted with `expires_at=None`: ```python 'expires_at': token.get('expires_at'), # models/oauth_sessions.py:125 ``` ### Impact - `get_oauth_token` cannot evaluate `datetime.fromtimestamp(session.expires_at)` when it's `None`, causing either a TypeError or a silent skip. - Tokens are never proactively refreshed. The next tool invocation after the token actually expires (unknown to us) fails with a 401 from the resource. ### Location - `backend/open_webui/utils/oauth.py` ~ lines 881–882 (callback normalisation) - `backend/open_webui/models/oauth_sessions.py` ~ line 125 (persistence) - `backend/open_webui/utils/oauth.py` ~ line 706 (proactive-refresh check) ### Suggested fix - If the provider returns `expires_at` directly, trust it. - If neither `expires_in` nor `expires_at` is present, either (a) fall back to a conservative default (e.g. 1 hour) and log a warning, or (b) always attempt a silent refresh before using the token, and surface a clear re-auth error if refresh fails. - Guard the expiry comparison against `None` so it never throws.
Author
Owner

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

Addressed in dev.

<!-- gh-comment-id:4239409497 --> @tjbck commented on GitHub (Apr 13, 2026): Addressed in dev.
Author
Owner

@dhruval-gupta commented on GitHub (Apr 13, 2026):

Addressed in dev.

i saw that but i am using dev docker image but due to client id and other issues with static oauth2.1 i cannot fully test it e2e.

<!-- gh-comment-id:4239437323 --> @dhruval-gupta commented on GitHub (Apr 13, 2026): > Addressed in dev. i saw that but i am using dev docker image but due to client id and other issues with static oauth2.1 i cannot fully test it e2e.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/open-webui#58707