From ff3b5143a0b7000ca151c1c468aa5ee7921892a9 Mon Sep 17 00:00:00 2001 From: saurabh-gupta-maersk Date: Fri, 15 May 2026 14:39:42 +0530 Subject: [PATCH] fix(proxy): make model registration idempotent and surface DB errors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two related issues in add_new_model / _add_model_to_db: 1. When a caller provides model_info.id, LiteLLM uses it as the primary key (model_id) of LiteLLM_ProxyModelTable. If the caller retries after a partial failure (e.g. post-write steps failed), the second attempt hits a PK conflict. That exception is caught by the broad except block, silently swallowed, and surfaces as a generic HTTP 500 "Failed to add model to db" with no indication that the model was already registered. Fix: replace prisma create() with upsert() in _add_model_to_db so that re-registering the same model_id is idempotent — the existing record is returned instead of raising a PK conflict. 2. The broad except in add_new_model swallows the real exception and lets execution continue with model_response=None, producing a misleading error message that hides the actual failure from callers and makes debugging very difficult. Fix: re-raise as HTTPException with the actual error message included, so callers receive actionable information instead of "Check your server logs for more details." --- .../model_management_endpoints.py | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/litellm/proxy/management_endpoints/model_management_endpoints.py b/litellm/proxy/management_endpoints/model_management_endpoints.py index af84bc123ff..5ab12b109de 100644 --- a/litellm/proxy/management_endpoints/model_management_endpoints.py +++ b/litellm/proxy/management_endpoints/model_management_endpoints.py @@ -317,8 +317,20 @@ async def _add_model_to_db( if model_params.model_info.id is not None: _data["model_id"] = model_params.model_info.id if should_create_model_in_db: - model_response = await prisma_client.db.litellm_proxymodeltable.create( - data=_data # type: ignore + # Use upsert so that re-registering a model with the same model_id (which + # becomes the primary key) is idempotent. Without this, a caller that retries + # after a partial failure receives a PK conflict exception that gets silently + # swallowed upstream, surfacing as a misleading "Failed to add model to db" 500. + model_response = await prisma_client.db.litellm_proxymodeltable.upsert( + where={"model_id": _data["model_id"]}, # type: ignore + data={ + "create": _data, # type: ignore + "update": { + k: v + for k, v in _data.items() + if k not in ("model_id", "created_by") + }, + }, ) else: model_response = LiteLLM_ProxyModelTable(**_data) @@ -1018,6 +1030,12 @@ async def add_new_model( ) except Exception as e: verbose_proxy_logger.exception(f"Exception in add_new_model: {e}") + raise HTTPException( + status_code=500, + detail={ + "error": f"Failed to add model to db: {str(e)}" + }, + ) else: raise HTTPException(