From 9d7dea42d0b7da38e954cd3706f0278e6dbd8a83 Mon Sep 17 00:00:00 2001 From: Alexsander Hamir Date: Fri, 10 Oct 2025 17:50:51 -0700 Subject: [PATCH] [Fix] - SensitiveDataMasker converts lists to string (#15420) * fix: preserve lists in SensitiveDataMasker to prevent string conversion Added 'list' to allowed primitive types in mask_dict() to prevent lists like tags from being converted to string representations in API responses. Before: {"tags": "['East US 2', 'production', 'test']"} After: {"tags": ["East US 2", "production", "test"]} * add: unit test --- .../sensitive_data_masker.py | 8 +++-- .../test_sensitive_data_masker.py | 31 +++++++++++++++++++ 2 files changed, 36 insertions(+), 3 deletions(-) create mode 100644 tests/test_litellm/litellm_core_utils/test_sensitive_data_masker.py diff --git a/litellm/litellm_core_utils/sensitive_data_masker.py b/litellm/litellm_core_utils/sensitive_data_masker.py index 05f1a37ca1..ea0bed3041 100644 --- a/litellm/litellm_core_utils/sensitive_data_masker.py +++ b/litellm/litellm_core_utils/sensitive_data_masker.py @@ -75,7 +75,7 @@ class SensitiveDataMasker: masked_data[k] = self._mask_value(str_value) else: masked_data[k] = ( - v if isinstance(v, (int, float, bool, str)) else str(v) + v if isinstance(v, (int, float, bool, str, list)) else str(v) ) except Exception: masked_data[k] = "" @@ -89,12 +89,14 @@ masker = SensitiveDataMasker() data = { "api_key": "sk-1234567890abcdef", "redis_password": "very_secret_pass", - "port": 6379 + "port": 6379, + "tags": ["East US 2", "production", "test"] } masked = masker.mask_dict(data) # Result: { # "api_key": "sk-1****cdef", # "redis_password": "very****pass", -# "port": 6379 +# "port": 6379, +# "tags": ["East US 2", "production", "test"] # } """ diff --git a/tests/test_litellm/litellm_core_utils/test_sensitive_data_masker.py b/tests/test_litellm/litellm_core_utils/test_sensitive_data_masker.py new file mode 100644 index 0000000000..6356c5137b --- /dev/null +++ b/tests/test_litellm/litellm_core_utils/test_sensitive_data_masker.py @@ -0,0 +1,31 @@ +""" +Unit tests for SensitiveDataMasker - List Preservation +""" + +import os +import sys + +import pytest + +# Add the parent directory to the system path +sys.path.insert(0, os.path.abspath("../../..")) + +from litellm.litellm_core_utils.sensitive_data_masker import SensitiveDataMasker + + +def test_lists_are_preserved_not_converted_to_strings(): + """ + Regression test: Ensure lists are preserved as JSON arrays, not converted to strings. + Previously, tags field in /model/info was returned as "['tag1', 'tag2']" instead of ["tag1", "tag2"] + """ + masker = SensitiveDataMasker() + + data = { + "tags": ["East US 2", "production", "test"], + } + + masked = masker.mask_dict(data) + + # Must be a list, not a string + assert isinstance(masked["tags"], list) + assert masked["tags"] == ["East US 2", "production", "test"]