{"record":{"id":"1a489575b2c65e6c","repo":"agentscope-ai/agentscope","slug":"tts-model-is-not-connected-call-connect-first","errorCode":null,"errorMessage":"TTS model is not connected. Call `connect()` first.","messagePattern":"TTS model is not connected\\. Call `connect\\(\\)` first\\.","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"src/agentscope/tts/_dashscope/_cosyvoice_model.py","lineNumber":230,"sourceCode":"        except Exception:\n            pass\n        self._connected = False\n        self._cold_start_buffer = \"\"\n        self._cold_start_done = False\n        await self.connect()\n\n    async def push(\n        self,\n        text: str,\n        **kwargs: Any,\n    ) -> TTSResponse:\n        \"\"\"Push an incremental text delta for realtime synthesis.\"\"\"\n        del kwargs\n        if not self.realtime:\n            return await super().push(text)\n\n        if not self._connected:\n            raise RuntimeError(\n                \"TTS model is not connected. Call `connect()` first.\",\n            )\n\n        if not text:\n            return TTSResponse(content=None)\n\n        self._accumulated_text += text\n\n        if self._cold_start_done:\n            text_to_send = text\n        else:\n            self._cold_start_buffer += text\n            if (\n                self.cold_start_length\n                and len(self._cold_start_buffer) < self.cold_start_length\n            ) or (\n                self.cold_start_words\n                and len(self._cold_start_buffer.split())","sourceCodeStart":212,"sourceCodeEnd":248,"githubUrl":"https://github.com/agentscope-ai/agentscope/blob/e90f1c7592896cc95f6e5ee506194f533378247d/src/agentscope/tts/_dashscope/_cosyvoice_model.py#L212-L248","documentation":"DashScope CosyVoice TTS raises RuntimeError from push() when you push incremental text deltas for realtime synthesis before the underlying realtime session is connected. The model requires connect() to establish the websocket session first.","triggerScenarios":"Calling await model.push(delta) with realtime=True before ever calling await model.connect(), or after disconnect()/a dropped session (the _connected flag is False).","commonSituations":"Streaming pipelines that start pushing text immediately without awaiting connect(); reconnect logic that forgets to re-connect after a drop; using the realtime code path when you meant one-shot synthesize (which doesn't need a session).","solutions":["Call `await model.connect()` and await it fully before the first push()","After any disconnect or error, re-run connect() before pushing again","If you don't need streaming, construct/use the model without realtime mode so push() goes through the non-realtime path"],"exampleFix":"# before\nasync for delta in stream:\n    resp = await tts.push(delta)   # RuntimeError: not connected\n# after\nawait tts.connect()\nasync for delta in stream:\n    resp = await tts.push(delta)","handlingStrategy":"validation","validationCode":"if not tts._connected:\n    await tts.connect()\nresp = await tts.push(delta)","typeGuard":null,"tryCatchPattern":"try:\n    resp = await tts.push(delta)\nexcept RuntimeError as e:\n    if 'not connected' in str(e):\n        await tts.connect()\n        resp = await tts.push(delta)\n    else:\n        raise","preventionTips":["Await connect() in the same async setup that creates the TTS model","Track session state and reconnect before pushing after any error/disconnect"],"tags":["tts","dashscope","cosyvoice","realtime","connection"],"backgroundTag":"client-not-connected","analyzedSha":"e90f1c7592896cc95f6e5ee506194f533378247d","analyzedAt":"2026-08-28T18:24:12.087Z","schemaVersion":2},"datasetVersion":"2026-08-28T21:17:43.275Z"}