{"record":{"id":"8b83ce5327d61d34","repo":"BigPizzaV3/CodexPlusPlus","slug":"login","errorCode":null,"errorMessage":"\n二维码已过期，请重新运行 login。","messagePattern":"\n二维码已过期，请重新运行 login。","errorType":"exception","errorClass":"SystemExit","httpStatus":null,"severity":"warning","filePath":"tools/codex-wechat/codex_wechat.py","lineNumber":810,"sourceCode":"        elif status == \"confirmed\":\n            token = str(status_resp.get(\"bot_token\") or \"\")\n            account_id = str(status_resp.get(\"ilink_bot_id\") or \"\")\n            base_url = str(status_resp.get(\"baseurl\") or current_base or ILINK_BASE_URL)\n            user_id = str(status_resp.get(\"ilink_user_id\") or \"\")\n            if not token or not account_id:\n                raise SystemExit(\"扫码成功但没有拿到 bot_token/account_id。\")\n\n            config = load_json_file(output) if output.exists() else {}\n            config.update({\"base_url\": base_url, \"token\": token, \"account_id\": account_id})\n            if user_id:\n                config[\"login_user_id\"] = user_id\n            output.parent.mkdir(parents=True, exist_ok=True)\n            output.write_text(json.dumps(config, ensure_ascii=False, indent=2) + \"\\n\", \"utf-8\")\n            print(f\"\\n登录成功，配置已写入：{output}\")\n            print(\"注意：该文件包含微信 iLink token，不要提交到 Git。\")\n            return\n        elif status == \"expired\":\n            raise SystemExit(\"\\n二维码已过期，请重新运行 login。\")\n        time.sleep(1)\n\n    raise SystemExit(\"\\n登录超时。\")\n\n\ndef main(argv: list[str]) -> int:\n    parser = argparse.ArgumentParser(description=\"Codex WeChat Claw PoC\")\n    sub = parser.add_subparsers(dest=\"command\", required=True)\n\n    run_parser = sub.add_parser(\"run\", help=\"启动 iLink -> codex app-server/exec -> iLink 转发\")\n    run_parser.add_argument(\"--config\", required=True, type=Path, help=\"配置文件路径\")\n\n    login_parser = sub.add_parser(\"login\", help=\"扫码获取 iLink token 并写入配置\")\n    login_parser.add_argument(\"--output\", required=True, type=Path, help=\"要写入的本地配置文件\")\n    login_parser.add_argument(\"--bot-type\", default=\"3\", help=\"iLink bot_type，默认 3\")\n    login_parser.add_argument(\"--timeout\", default=480, type=int, help=\"扫码超时时间，秒\")\n\n    args = parser.parse_args(argv)","sourceCodeStart":792,"sourceCodeEnd":828,"githubUrl":"https://github.com/BigPizzaV3/CodexPlusPlus/blob/b1ed92e5e4a2d74095d4b8db5af43cef7acba9c6/tools/codex-wechat/codex_wechat.py#L792-L828","documentation":"During qr_login polling, when the status endpoint reports \"expired\", the QR code is no longer valid and the login must be restarted from a fresh code. The tool raises SystemExit immediately instead of continuing to poll. QR codes have a server-enforced lifetime, so expiry is a normal, expected terminal state.","triggerScenarios":"While polling in qr_login, a status response with status == \"expired\" is received before the loop returns (confirmed) or the timeout elapses. Raised from `raise SystemExit(\"\\n二维码已过期，请重新运行 login。\")`, called from `main` via the login subcommand.","commonSituations":"User waited too long before scanning (most QR codes expire in ~1–2 minutes); slow network/proxy causing polls to miss the confirmation window; user scanned after the code had already lapsed; running login unattended and returning to it late.","solutions":["Re-run `codex-wechat login` to generate a fresh QR code and scan it promptly.","Scan the QR code immediately after it is displayed; do not let it sit.","If expiry happens consistently quickly, pass a longer --timeout so polling continues across multiple code lifecycles is not needed — instead just retry; check server-side expiry policy.","Check network latency to the iLink endpoint; excessive delays can cause the poll to observe expired before confirmed."],"exampleFix":"null","handlingStrategy":"retry","validationCode":"# check code age before prompting the user to scan\nif time.monotonic() - qr_created_at > QR_TTL_SECONDS:\n    qr = regenerate_qr()  # refresh before it expires","typeGuard":null,"tryCatchPattern":"try:\n    qr_login(output, bot_type, timeout)\nexcept SystemExit as e:\n    if \"已过期\" in str(e):\n        qr_login(output, bot_type, timeout)  # regenerate and retry once","preventionTips":["Scan the QR code immediately after it renders.","Regenerate the QR automatically on expiry instead of exiting.","Run login interactively, not in unattended scripts."],"tags":["login","qr-code","timeout","authentication"],"backgroundTag":"request-timeout","analyzedSha":"b1ed92e5e4a2d74095d4b8db5af43cef7acba9c6","analyzedAt":"2026-09-19T23:35:21.129Z","contentChangedAt":"2026-09-19T23:35:21.129Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}