BigPizzaV3/CodexPlusPlus · warning · SystemExit
二维码已过期,请重新运行 login。
Error message
二维码已过期,请重新运行 login。
What it means
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.
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.
Example fix
null
Defensive patterns
Strategy: retry
Validate before calling
# check code age before prompting the user to scan
if time.monotonic() - qr_created_at > QR_TTL_SECONDS:
qr = regenerate_qr() # refresh before it expires Try / catch
try:
qr_login(output, bot_type, timeout)
except SystemExit as e:
if "已过期" in str(e):
qr_login(output, bot_type, timeout) # regenerate and retry once Prevention
- Scan the QR code immediately after it renders.
- Regenerate the QR automatically on expiry instead of exiting.
- Run login interactively, not in unattended scripts.
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: Request timed out: what client-side request timeouts mean across libraries (Request timed out, TIMED_OUT, APITimeoutError) — this error's family across 39 libraries.
Related errors
AI-assisted analysis of BigPizzaV3/CodexPlusPlus@b1ed92e5e4 (2026-09-19).
Data as JSON: /api/errors/8b83ce5327d61d34.
Report an issue: GitHub.
Appendix: source
Thrown at tools/codex-wechat/codex_wechat.py:810
elif status == "confirmed":
token = str(status_resp.get("bot_token") or "")
account_id = str(status_resp.get("ilink_bot_id") or "")
base_url = str(status_resp.get("baseurl") or current_base or ILINK_BASE_URL)
user_id = str(status_resp.get("ilink_user_id") or "")
if not token or not account_id:
raise SystemExit("扫码成功但没有拿到 bot_token/account_id。")
config = load_json_file(output) if output.exists() else {}
config.update({"base_url": base_url, "token": token, "account_id": account_id})
if user_id:
config["login_user_id"] = user_id
output.parent.mkdir(parents=True, exist_ok=True)
output.write_text(json.dumps(config, ensure_ascii=False, indent=2) + "\n", "utf-8")
print(f"\n登录成功,配置已写入:{output}")
print("注意:该文件包含微信 iLink token,不要提交到 Git。")
return
elif status == "expired":
raise SystemExit("\n二维码已过期,请重新运行 login。")
time.sleep(1)
raise SystemExit("\n登录超时。")
def main(argv: list[str]) -> int:
parser = argparse.ArgumentParser(description="Codex WeChat Claw PoC")
sub = parser.add_subparsers(dest="command", required=True)
run_parser = sub.add_parser("run", help="启动 iLink -> codex app-server/exec -> iLink 转发")
run_parser.add_argument("--config", required=True, type=Path, help="配置文件路径")
login_parser = sub.add_parser("login", help="扫码获取 iLink token 并写入配置")
login_parser.add_argument("--output", required=True, type=Path, help="要写入的本地配置文件")
login_parser.add_argument("--bot-type", default="3", help="iLink bot_type,默认 3")
login_parser.add_argument("--timeout", default=480, type=int, help="扫码超时时间,秒")
args = parser.parse_args(argv)View on GitHub (pinned to b1ed92e5e4)