BigPizzaV3/CodexPlusPlus · error · SystemExit
扫码成功但没有拿到 bot_token/account_id。
Error message
扫码成功但没有拿到 bot_token/account_id。
What it means
qr_login polls the WeChat iLink login status endpoint after the QR code is scanned and confirmed. When the confirmed response lacks a non-empty bot_token or ilink_bot_id (account_id), the tool cannot write a usable login config, so it raises SystemExit. This guards against saving a config file that would fail later during run.
Solutions
- Re-run `codex-wechat login` — the failure is often transient on the iLink side; a fresh QR login usually returns the token.
- Print/inspect the raw status_resp (add a debug dump before the raise) to see which fields the server actually returned and whether field names changed.
- Verify the baseurl being used (status_resp baseurl vs current_base vs ILINK_BASE_URL); a wrong or outdated ILINK_BASE_URL can hit an endpoint that returns a different response shape.
- Check whether the WeChat iLink bot API updated field names (e.g. token vs bot_token) and patch the extraction in qr_login accordingly.
- Confirm the bot was fully registered/approved on the WeChat side; an unprovisioned bot can be confirmed without a token.
Example fix
// before
if not token or not account_id:
raise SystemExit("扫码成功但没有拿到 bot_token/account_id。")
// after
if not token or not account_id:
print(f"debug status_resp={status_resp!r}") # inspect actual payload
raise SystemExit("扫码成功但没有拿到 bot_token/account_id。") Defensive patterns
Strategy: validation
Validate before calling
# before trusting the confirmed response
resp = poll_status(...)
if resp.get("status") == "confirmed":
if not resp.get("bot_token") or not resp.get("ilink_bot_id"):
raise RuntimeError(f"confirmed response missing credentials: {resp}") Type guard
def has_credentials(resp: dict) -> bool:
return bool(resp.get("bot_token")) and bool(resp.get("ilink_bot_id")) Prevention
- Log the full status payload on every poll so missing fields are diagnosable.
- Pin/verify the iLink API version and field names in one constants module.
- Test qr_login against a stub server that returns confirmed-without-token to keep the guard exercised.
When it happens
Trigger: The status endpoint returns status == "confirmed" but status_resp.get("bot_token") or status_resp.get("ilink_bot_id") is missing, None, or an empty string. Raised via `raise SystemExit("扫码成功但没有拿到 bot_token/account_id。")` inside qr_login, called from `main` with the login subcommand.
Common situations: WeChat iLink server-side issues where the confirmation response omits credentials; an API version change renaming bot_token/ilink_bot_id fields; a proxy or modified baseurl (ILINK_BASE_URL override) returning an unexpected response shape; partial bot registration on the WeChat side so the bot exists but no token was issued.
Related errors
AI-assisted analysis of BigPizzaV3/CodexPlusPlus@b1ed92e5e4 (2026-09-19).
Data as JSON: /api/errors/eafbca3f7f36679e.
Report an issue: GitHub.
Appendix: source
Thrown at tools/codex-wechat/codex_wechat.py:798
timeout=35,
)
status = str(status_resp.get("status") or "wait")
if status == "wait":
print(".", end="", flush=True)
elif status == "scaned":
print("\n已扫码,请在微信中确认。")
elif status == "scaned_but_redirect":
redirect_host = str(status_resp.get("redirect_host") or "")
if redirect_host:
current_base = "https://" + redirect_host
print(f"\n切换 iLink base_url:{current_base}")
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:View on GitHub (pinned to b1ed92e5e4)