From 3afe2e6d56ef1eec5d821e962ee9d557f5b92400 Mon Sep 17 00:00:00 2001 From: Classic298 <27028174+Classic298@users.noreply.github.com> Date: Sun, 30 Aug 2026 22:22:42 +0200 Subject: [PATCH] fix: only record the cache epoch after a successful refresh A refresh that came back empty (every provider unreachable, a transient upstream failure) kept the old model list but still marked the instance as caught up, so it never retried and served the pre-change models until restart. The epoch is now stored only when the fetch actually returned models. The openai epoch bump moves into the connection config write, the same shape ollama already uses, so it lands in one transaction instead of two and the shared cache helper stays as it was on dev. The epoch check now just sets `refresh` instead of carrying a second flag, and the initial process state is seeded to the config default so a fresh worker does not start out looking stale. --- backend/open_webui/main.py | 2 +- backend/open_webui/routers/openai.py | 11 +++++++++-- backend/open_webui/utils/models.py | 11 ++++++----- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/backend/open_webui/main.py b/backend/open_webui/main.py index 914c0620b8..36043d071a 100644 --- a/backend/open_webui/main.py +++ b/backend/open_webui/main.py @@ -587,7 +587,7 @@ app.state.SCIM_TOKEN = SCIM_TOKEN ######################################## app.state.BASE_MODELS = [] -app.state.BASE_MODELS_EPOCH = None +app.state.BASE_MODELS_EPOCH = '' ######################################## # diff --git a/backend/open_webui/routers/openai.py b/backend/open_webui/routers/openai.py index 7ea9302d47..fc6a6ee180 100644 --- a/backend/open_webui/routers/openai.py +++ b/backend/open_webui/routers/openai.py @@ -345,7 +345,6 @@ async def get_openai_connection(idx: int) -> tuple[str, str, dict]: async def clear_openai_model_cache(request: Request): - await Config.upsert({'models.base_models_cache_epoch': str(uuid4())}) await get_all_models.cache.clear() request.app.state.BASE_MODELS = [] request.app.state.OPENAI_MODELS = {} @@ -570,10 +569,18 @@ async def update_config(request: Request, form_data: OpenAIConfigForm, user=Depe 'openai.api_base_urls': form_data.OPENAI_API_BASE_URLS, 'openai.api_keys': api_keys, 'openai.api_configs': api_configs, + 'models.base_models_cache_epoch': str(uuid4()), } ) - await clear_openai_model_cache(request) + await get_all_models.cache.clear() + request.app.state.BASE_MODELS = [] + request.app.state.OPENAI_MODELS = {} + models = getattr(request.app.state, 'MODELS', None) + if hasattr(models, 'clear'): + models.clear() + else: + request.app.state.MODELS = {} await publish_event( request, diff --git a/backend/open_webui/utils/models.py b/backend/open_webui/utils/models.py index d55c5b52bc..89e104a869 100644 --- a/backend/open_webui/utils/models.py +++ b/backend/open_webui/utils/models.py @@ -72,25 +72,26 @@ async def get_all_models(request, refresh: bool = False, user: UserModel = None) 'evaluation.arena.models', 'models.default_metadata', ) - # A changed epoch means another instance edited a provider, so our cached models are stale. cache_epoch = config.get('models.base_models_cache_epoch') - stale = request.app.state.BASE_MODELS_EPOCH != cache_epoch + if request.app.state.BASE_MODELS_EPOCH != cache_epoch: + # Another instance changed a provider connection, so our cached models are outdated. + refresh = True - if refresh or stale: + if refresh: await openai.get_all_models.cache.clear() await ollama.get_all_models.cache.clear() if ( request.app.state.MODELS and request.app.state.BASE_MODELS - and (config.get('models.base_models_cache') and not (refresh or stale)) + and (config.get('models.base_models_cache') and not refresh) ): base_models = request.app.state.BASE_MODELS else: base_models = await get_all_base_models(request, user=user) - request.app.state.BASE_MODELS_EPOCH = cache_epoch if base_models: request.app.state.BASE_MODELS = base_models + request.app.state.BASE_MODELS_EPOCH = cache_epoch else: base_models = request.app.state.BASE_MODELS