From 238da9115419c5d8909633e42bc089cdeec1fd50 Mon Sep 17 00:00:00 2001 From: unknown <> Date: Wed, 1 Jul 2026 10:29:50 +0000 Subject: [PATCH] fix: handle non-JSON string values in ConfigRepository.get_param() Addresses Greptile review: get_param() now catches json.JSONDecodeError for corrupt/non-JSON string values in the DB instead of crashing config reload. Restores original test case using 'not_a_dict' string value. Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --- litellm/repositories/config_repository.py | 8 +++++++- tests/test_litellm/proxy/test_proxy_server.py | 2 +- tests/test_litellm/repositories/test_repositories.py | 11 +++++++++++ 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/litellm/repositories/config_repository.py b/litellm/repositories/config_repository.py index 5af78bf1a6c..8c1da6bfcf1 100644 --- a/litellm/repositories/config_repository.py +++ b/litellm/repositories/config_repository.py @@ -54,7 +54,13 @@ class ConfigRepository: return None param_value = record.param_value if isinstance(param_value, str): - param_value = json.loads(param_value) + try: + param_value = json.loads(param_value) + except (json.JSONDecodeError, ValueError): + verbose_proxy_logger.warning( + "config_repository.get_param: param_name=%s has non-JSON string value, returning as-is", + param_name, + ) return ConfigParam(param_name=param_name, param_value=param_value) async def set_param(self, param_name: str, param_value: Any) -> ConfigParam: diff --git a/tests/test_litellm/proxy/test_proxy_server.py b/tests/test_litellm/proxy/test_proxy_server.py index 88e9a4ecdab..1712ebbf067 100644 --- a/tests/test_litellm/proxy/test_proxy_server.py +++ b/tests/test_litellm/proxy/test_proxy_server.py @@ -3896,7 +3896,7 @@ async def test_add_router_settings_from_db_config_edge_cases(): # Test Case 6: DB config exists but param_value is not a dict mock_db_config_invalid = MagicMock() - mock_db_config_invalid.param_value = 42 + mock_db_config_invalid.param_value = "not_a_dict" mock_prisma_client.db.litellm_config.find_unique = AsyncMock( return_value=mock_db_config_invalid ) diff --git a/tests/test_litellm/repositories/test_repositories.py b/tests/test_litellm/repositories/test_repositories.py index af2eea823f4..e8ef8b70414 100644 --- a/tests/test_litellm/repositories/test_repositories.py +++ b/tests/test_litellm/repositories/test_repositories.py @@ -1387,6 +1387,17 @@ class TestConfigRepository: assert param.param_name == "general_settings" assert param.param_value["master_key"] == "test" + @pytest.mark.asyncio + async def test_get_param_non_json_string(self, repo): + """Non-JSON string values in the DB should not crash get_param.""" + repo._prisma_client.db.litellm_config._records["router_settings"] = { + "param_name": "router_settings", + "param_value": "not_valid_json", + } + param = await repo.get_param("router_settings") + assert param is not None + assert param.param_value == "not_valid_json" + @pytest.mark.asyncio async def test_set_param(self, repo): param = await repo.set_param("test_param", {"key": "value"})