{"record":{"id":"90fe138bd6e85046","repo":"HKUDS/Vibe-Trading","slug":"getupdates-failed-ret-ret-errcode-errcode-err","errorCode":null,"errorMessage":"getUpdates failed: ret={ret} errcode={errcode} errmsg={data.get('errmsg', '')}","messagePattern":"getUpdates failed: ret=(.+?) errcode=(.+?) errmsg=(.+?)","errorType":"error_code","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"agent/src/channels/weixin.py","lineNumber":571,"sourceCode":"        data = await self._api_post(\"ilink/bot/getupdates\", body)\n\n        # Check for API-level errors (monitor.ts checks both ret and errcode)\n        ret = data.get(\"ret\", 0)\n        errcode = data.get(\"errcode\", 0)\n\n        is_error = (ret is not None and ret != 0) or (errcode is not None and errcode != 0)\n\n        if is_error:\n            if errcode == ERRCODE_SESSION_EXPIRED or ret == ERRCODE_SESSION_EXPIRED:\n                self._pause_session()\n                remaining = self._session_pause_remaining_s()\n                self.logger.warning(\n                    \"session expired (errcode {}). Pausing {} min.\",\n                    errcode,\n                    max((remaining + 59) // 60, 1),\n                )\n                return\n            raise RuntimeError(\n                f\"getUpdates failed: ret={ret} errcode={errcode} errmsg={data.get('errmsg', '')}\"\n            )\n\n        # Honour server-suggested poll timeout (monitor.ts:102-105)\n        server_timeout_ms = data.get(\"longpolling_timeout_ms\")\n        if server_timeout_ms and server_timeout_ms > 0:\n            self._next_poll_timeout_s = max(server_timeout_ms // 1000, 5)\n\n        # Update cursor\n        new_buf = data.get(\"get_updates_buf\", \"\")\n        if new_buf:\n            self._get_updates_buf = new_buf\n            self._save_state()\n\n        # Process messages (WeixinMessage[] from types.ts)\n        msgs: list[dict] = data.get(\"msgs\", []) or []\n        for msg in msgs:\n            try:","sourceCodeStart":553,"sourceCodeEnd":589,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/channels/weixin.py#L553-L589","documentation":"Raised by the WeChat long-poll loop when the getUpdates-style call returns a non-zero ret or errcode that is not the recognized session-expired code. The library treats session expiry as a pause but surfaces any other poll failure as a RuntimeError including ret, errcode, and errmsg from the API response.","triggerScenarios":"_poll_once (started from start()) receives a poll response where ret != 0 or errcode != 0 and errcode is not ERRCODE_SESSION_EXPIRED — e.g. auth token invalid, malformed sync request, server 5xx disguised as error JSON, or rate limiting.","commonSituations":"Token revoked or stale after logging in from another device; WeChat server-side changes to the long-poll contract; clock skew or replayed sync keys; heavy polling causing temporary throttling.","solutions":["Match errcode/ret against WeChat iLink docs in the error message; auth-related codes mean re-login is required.","Implement retry with exponential backoff in the poll loop for transient (network/throttle) codes.","If token invalid, rerun the QR login flow to obtain a fresh session and token.","Verify the request payload (sync key / offset fields) is consistent between polls."],"exampleFix":"// before\nawait self._poll_once()\n\n// after\ntry:\n    await self._poll_once()\nexcept RuntimeError as e:\n    self.logger.warning(\"poll failed, backing off: {}\", e)\n    await asyncio.sleep(min(2 ** failures * 5, 300))","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try:\n    await channel._poll_once()\nexcept RuntimeError as e:\n    if \"getUpdates failed\" in str(e):\n        await asyncio.sleep(min(2 ** failures * 5, 300))\n        failures += 1\n    else:\n        raise","preventionTips":["Wrap poll loop in retry with exponential backoff.","Re-login on auth-related errcodes instead of tight-looping.","Log ret/errcode/errmsg for correlation with WeChat docs."],"tags":["wechat","long-polling","getupdates","api-error"],"backgroundTag":"long-poll-api-error","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}