diff --git a/services/tts/tts_service.py b/services/tts/tts_service.py index e724434cb..2120d7720 100644 --- a/services/tts/tts_service.py +++ b/services/tts/tts_service.py @@ -68,7 +68,7 @@ class TTSService: if provider == "local": kokoro = self._get_kokoro() return kokoro is not None and kokoro.available - if provider.startswith("endpoint:"): + if isinstance(provider, str) and provider.startswith("endpoint:"): return True # assume reachable; errors surface at synthesis time return False diff --git a/tests/test_tts_available_nonstring_provider.py b/tests/test_tts_available_nonstring_provider.py new file mode 100644 index 000000000..632e1cd89 --- /dev/null +++ b/tests/test_tts_available_nonstring_provider.py @@ -0,0 +1,17 @@ +from services.tts.tts_service import TTSService + + +def test_available_tolerates_non_string_provider(tmp_path): + """A hand-edited/corrupt data/settings.json can store a non-string + tts_provider (e.g. null or a number). available reads it and calls + provider.startswith("endpoint:"), which raised AttributeError on a + non-str. It must instead fall through and report unavailable.""" + service = TTSService(cache_dir=str(tmp_path)) + service._load_settings = lambda: { + "tts_enabled": True, + "tts_provider": 123, + "tts_model": "tts-1", + "tts_voice": "alloy", + "tts_speed": "1", + } + assert service.available is False