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

  1. Re-run `codex-wechat login` — the failure is often transient on the iLink side; a fresh QR login usually returns the token.
  2. 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.
  3. 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.
  4. Check whether the WeChat iLink bot API updated field names (e.g. token vs bot_token) and patch the extraction in qr_login accordingly.
  5. 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

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)