From 7f59d365a2dbcd7d6232c560d7baa25c4d7695db Mon Sep 17 00:00:00 2001 From: "zhenjun.chen" Date: Tue, 12 May 2026 15:12:52 +0800 Subject: [PATCH] fix: provider update silently drops model_type and endpoint_url MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `ProviderService.update()`'s `_UPDATABLE_FIELDS` whitelist contained two field names that don't exist on the `Provider` ORM model (`api_base` and `extra_config`) while missing three that do (`model_type`, `endpoint_url`, `encrypted_config`). Since the loop uses `setattr(model, key, value)` without a `hasattr` check, the typo'd entries silently no-op'd and the missing entries silently rejected legitimate updates from clients. Symptom: editing a BYOK provider's model name and clicking Save (which routes to PUT `/api/v1/provider/{id}`) appears to succeed (200 OK, validation passes), but the database row keeps the old value and the agent runtime continues using the previous model. Same for endpoint URL edits. Fix: replace the whitelist with the actual `Provider` field names (which also match the `ProviderIn` request schema), and add a comment explaining why the names must match verbatim. The whitelist still excludes identity / audit fields (`id`, `user_id`, timestamps) so the H10 security-by-design intent is preserved. The pre-existing `is_vaild` typo is project-wide (`Provider.is_vaild`, `VaildStatus`, etc.) and is kept as-is — out of scope for this fix. --- .../model_provider/service/provider_service.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/server/app/domains/model_provider/service/provider_service.py b/server/app/domains/model_provider/service/provider_service.py index 599d3f728..d0592b510 100644 --- a/server/app/domains/model_provider/service/provider_service.py +++ b/server/app/domains/model_provider/service/provider_service.py @@ -65,8 +65,18 @@ def update(provider_id: int, user_id: int, data: dict) -> dict: ).first() if not model: return {"success": False, "error_code": "PROVIDER_NOT_FOUND"} - # H10: only allow updating safe fields - _UPDATABLE_FIELDS = {"provider_name", "api_key", "api_base", "extra_config", "prefer", "is_vaild"} + # H10: only allow updating safe fields. Field names must match the + # `Provider` ORM model (and `ProviderIn` request schema) verbatim — + # `setattr(model, key, value)` silently no-ops on a missing field. + _UPDATABLE_FIELDS = { + "provider_name", + "api_key", + "model_type", + "endpoint_url", + "encrypted_config", + "prefer", + "is_vaild", + } for key, value in data.items(): if key in _UPDATABLE_FIELDS: setattr(model, key, value)