{"record":{"id":"3d00d0f6e5e491dc","repo":"HKUDS/nanobot","slug":"telegram-application-is-restarting-message-not-de","errorCode":null,"errorMessage":"Telegram application is restarting; message not delivered","messagePattern":"Telegram application is restarting; message not delivered","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"nanobot/channels/telegram/runtime.py","lineNumber":747,"sourceCode":"        bound webhook port raises OSError.\n        \"\"\"\n        return isinstance(exc, NetworkError | TimedOut | asyncio.TimeoutError)\n\n    async def _wait_for_app(self) -> TelegramApplication | None:\n        \"\"\"Return the live app, briefly waiting out an in-flight rebuild.\n\n        Returning quietly while ``start()`` rebuilds would let the manager count\n        the message as delivered, so raise once the wait runs out. None means the\n        channel is stopped: nothing left to deliver.\n        \"\"\"\n        if self._app_ready.is_set() and self._app is not None:\n            return self._app\n        if not self._running:\n            return None\n        with suppress(asyncio.TimeoutError):\n            await asyncio.wait_for(self._app_ready.wait(), APP_RESTART_SEND_WAIT_SECONDS)\n        if not self._app_ready.is_set() or self._app is None:\n            raise RuntimeError(\"Telegram application is restarting; message not delivered\")\n        return self._app\n\n    def _note_poll_ok(self) -> None:\n        # HTTP error statuses count too: the watchdog detects transport stalls,\n        # not logical failures.\n        self._last_poll_ok = time.monotonic()\n\n    async def _watch_polling(self) -> bool:\n        \"\"\"Idle until stop(); in polling mode, return True when getUpdates goes stale.\"\"\"\n        watch = self.config.mode != \"webhook\"\n        while self._running:\n            await asyncio.sleep(POLL_WATCH_INTERVAL)\n            if watch and time.monotonic() - self._last_poll_ok > POLL_STALE_SECONDS:\n                return True\n        return False\n\n    async def _idle(self, seconds: float) -> None:\n        \"\"\"Sleep in short steps so stop() stays responsive.\"\"\"","sourceCodeStart":729,"sourceCodeEnd":765,"githubUrl":"https://github.com/HKUDS/nanobot/blob/42f37dc4c0e409eac7818a82d165c5f2757bc075/nanobot/channels/telegram/runtime.py#L729-L765","documentation":"In _wait_for_app(), a send (or send_delta) was attempted while the Telegram application is not live: _app_ready stayed unset after waiting APP_RESTART_SEND_WAIT_SECONDS for start() to finish rebuilding the app. Returning quietly would let the channel manager count the message as delivered, so this RuntimeError explicitly signals non-delivery so the buffered send can be retried later.","triggerScenarios":"Thrown at nanobot/channels/telegram/runtime.py:747 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Let the channel manager retry the buffered message once the app is rebuilt","Check gateway logs for why start() is repeatedly rebuilding (polling stalls, network errors)","Increase APP_RESTART_SEND_WAIT_SECONDS only if rebuilds are legitimately slow"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"42f37dc4c0e409eac7818a82d165c5f2757bc075","analyzedAt":"2026-08-26T00:18:52.276Z","contentChangedAt":"2026-08-26T00:18:52.276Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}