adorable-bear-14321
04/15/2026, 9:50 AMdef create_stt(self, agent_info: AgentInfo):
return stt.FallbackAdapter([
_build_sarvam_stt_instance(self, agent_info),
_build_azure_stt_instance(self, agent_info),
])
def _build_sarvam_stt_instance(provider: STTProvider, agent_info: AgentInfo):
stt_details: STTDetails = agent_info.config.stt_details
return sarvam.STT(
model=agent_info.model_values.stt.model or provider.get_config_value('sarvam', 'model', ),
language=stt_details.language or provider.get_config_value('sarvam', 'language', ),
mode=stt_details.mode,
prompt=stt_details.prompt or provider.get_config_value('sarvam', 'prompt', ),
high_vad_sensitivity=stt_details.high_vad_sensitivity or provider.get_config_value(
'sarvam', 'high_vad_sensitivity', ),
sample_rate=stt_details.sample_rate or provider.get_config_value('sarvam', 'sample_rate', 'int'),
flush_signal=stt_details.flush_signal or provider.get_config_value('sarvam', 'flush_signal', ),
input_audio_codec=stt_details.input_audio_codec or provider.get_config_value('sarvam', 'input_audio_codec', ),
)
def _build_azure_stt_instance(provider: STTProvider, agent_info: AgentInfo) -> azure_stt_1_3x.STT:
stt_details: STTDetails = agent_info.config.stt_details
profanity_option = AzureSTTProvider.get_profanity_option(
stt_details.profanity or provider.get_config_value('azure', 'profanity', ))
languages = stt_details.languages
if languages is None:
languages = []
single_language = stt_details.language
combined_languages = [
lang.strip()
for lang in (languages + ([single_language] if single_language else []))
if lang and lang.strip()
]
return azure_stt_1_3x.STT(
speech_key=stt_details.speech_key or provider.get_config_value('azure', 'speech_key_env', 'env'),
speech_region=stt_details.speech_region or provider.get_config_value('azure', 'speech_region_env', 'env'),
speech_auth_token=stt_details.speech_auth_token or provider.get_config_value('azure', 'speech_auth_token', ),
sample_rate=stt_details.sample_rate or provider.get_config_value('azure', 'sample_rate', 'int'),
num_channels=stt_details.num_channels or provider.get_config_value('azure', 'num_channels', 'int'),
segmentation_silence_timeout_ms=stt_details.segmentation_silence_timeout_ms or provider.get_config_value(
'azure', 'segmentation_silence_timeout_ms', 'int'),
segmentation_max_time_ms=stt_details.segmentation_max_time_ms or provider.get_config_value(
'azure', 'segmentation_max_time_ms', 'int'),
segmentation_strategy=stt_details.segmentation_strategy or provider.get_config_value(
'azure', 'segmentation_strategy', ),
language=combined_languages,
profanity=profanity_option,
)
this is the code
suppose i have passed sarvam config with language = hiiii
"unhandled exception while running the job task\nTraceback (most recent call last):\n File \"/Users/harshita.patil/whizdm-dev/livekit-agent/.venv/lib/python3.11/site-packages/opentelemetry/util/_decorator.py\", line 71, in async_wrapper\n return await func(*args, **kwargs) # type: ignore\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n File \"/Users/harshita.patil/whizdm-dev/livekit-agent/.venv/lib/python3.11/site-packages/livekit/agents/ipc/job_proc_lazy_main.py\", line 306, in _traceable_entrypoint\n await self._job_entrypoint_fnc(job_ctx)\n File \"/Users/harshita.patil/whizdm-dev/livekit-agent/agents/agent.py\", line 1052, in entrypoint\n @session.on(\"metrics_collected\")\n ^^^^^^^^^^\nAttributeError: 'NoneType' object has no attribute 'on'", "level": "ERROR", "name": "livekit.agents", "exc_info": "Traceback (most recent call last):\n File \"/Users/harshita.patil/whizdm-dev/livekit-agent/.venv/lib/python3.11/site-packages/opentelemetry/util/_decorator.py\", line 71, in async_wrapper\n return await func(*args, **kwargs) # type: ignore\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n File \"/Users/harshita.patil/whizdm-dev/livekit-agent/.venv/lib/python3.11/site-packages/livekit/agents/ipc/job_proc_lazy_main.py\", line 306, in _traceable_entrypoint\n await self._job_entrypoint_fnc(job_ctx)\n File \"/Users/harshita.patil/whizdm-dev/livekit-agent/agents/agent.py\", line 1052, in entrypoint\n @session.on(\"metrics_collected\")\n ^^^^^^^^^^\nAttributeError: 'NoneType' object has no attribute 'on'", "pid": 59798, "job_id": "AJ_W2xx6dXw2263", "room_id": "RM_y3sADj829qxm", "timestamp": "2026-04-15T094159.954416+00:00"}
{"message":
it directly fails the stt and terminate the session instead it should switch to the fallbacktall-airline-16756
04/15/2026, 9:50 AMtall-airline-16756
04/15/2026, 9:50 AMAttributeError: 'NoneType' object has no attribute 'on', and instead of falling back to Azure the session is terminated. I’ll help troubleshoot and get fallback working.
First quick checks (please confirm):
• Did you validate the Sarvam language value (e.g., a supported ISO code)? If not, please try a known-good language code.
• Can you share whether any Sarvam or Azure required env vars / keys are missing or invalid?
Immediate actionable steps to isolate and fix the fallback behavior:
1. Prevent initialization exceptions from killing the session
◦ Wrap each STT instance creation in a try/except and log failures. If an instance fails to construct, skip it rather than letting the exception propagate.
◦ Example pattern:
▪︎ Try to build Sarvam; on exception log error and continue.
▪︎ Try to build Azure; on exception log error and continue.
▪︎ If no instances remain, fail gracefully with a clear message.
1. Verify each STT instance independently
◦ Initialize and test Sarvam and Azure separately (outside of FallbackAdapter) to confirm they construct and start without errors.
◦ This will reveal if an invalid language or missing credential causes immediate failure.
1. Validate configuration values early
◦ Add validation for language codes and required keys when reading agent_info.config.stt_details. Reject invalid values with a clear error before initializing STT objects.
◦ For Sarvam: ensure language is a supported code. For Azure: ensure speech_key, speech_region, etc., are present.
1. Ensure FallbackAdapter gets only valid instances
◦ Build a list of successfully-initialized STT instances, then pass that list to FallbackAdapter. If the list is empty, handle that as a session setup failure (with a descriptive error), not an unhandled exception.
1. Investigate the 'NoneType' object has no attribute 'on' location
◦ That traceback shows @session.on("metrics_collected") where session is None. This likely means session initialization was aborted by an earlier exception (e.g., STT init). After you add defensive handling around STT construction, re-run and confirm session is created successfully.
If you’d like, share:
• The updated code after adding try/except around STT builds, or
• The Sarvam language value and relevant log lines when you build Sarvam.
I can then suggest a concrete code snippet to integrate into your builder logic and confirm the fallback will work.
Sources: Build a multilingual voice agent that automatically switches languages | Li... | Azure OpenAI LLM plugin guide | LiveKit Documentation | examples/voice_agents | livekit/livekit_composite | DeepWiki | Sarvam STT plugin guide | LiveKit Documentation | Azure Speech STT plugin guide | LiveKit Documentation, with interactive elementsadorable-bear-14321
04/15/2026, 9:51 AMtall-airline-16756
04/15/2026, 9:51 AMimport logging
from typing import List
logger = logging.getLogger(__name__)
def _is_valid_language(lang: str) -> bool:
# replace with real validation (e.g., check against supported ISO codes)
return bool(lang and len(lang) >= 2)
def create_stt(self, agent_info: AgentInfo):
stt_details = agent_info.config.stt_details
stt_instances: List[BaseSTT] = []
# Try Sarvam first
try:
lang = stt_details.language or self.get_config_value('sarvam', 'language')
if not _is_valid_language(lang):
raise ValueError(f"invalid sarvam language: {lang!r}")
sarvam_instance = _build_sarvam_stt_instance(self, agent_info)
stt_instances.append(sarvam_instance)
logger.info("Sarvam STT initialized")
except Exception as e:
logger.exception("Sarvam STT init failed, will try fallback: %s", e)
# Then Azure
try:
# Validate at least one language for Azure if required
azure_langs = (stt_details.languages or []) + ([stt_details.language] if stt_details.language else [])
if azure_langs and not all(_is_valid_language(l) for l in azure_langs):
raise ValueError(f"invalid azure languages: {azure_langs!r}")
azure_instance = _build_azure_stt_instance(self, agent_info)
stt_instances.append(azure_instance)
logger.info("Azure STT initialized")
except Exception as e:
logger.exception("Azure STT init failed: %s", e)
if not stt_instances:
# No valid STT providers — handle gracefully (do not let exception crash session)
logger.error("No STT providers available after validation. Proceeding without STT.")
return None # or return a NoOp STT implementation
# Create FallbackAdapter with only valid instances
return stt.FallbackAdapter(stt_instances)
If you want, I can:
• Provide a NoOp STT example to return when no providers are available, or
• Replace _is_valid_language with a real language-code check using a list you provide. Which would you prefer?, with interactive elements