HKUDS/Vibe-Trading · error · RuntimeError

Feishu / Lark registration did not return a login URL

Error message

Feishu / Lark registration did not return a login URL

What it means

Raised by _begin_registration when the Feishu/Lark device-code registration response contains a device_code but no verification_uri_complete field. The QR login flow cannot proceed because there is no URL to render as a QR code for the user to scan. It indicates the registration endpoint responded but with an incomplete/Unexpected payload.

Source

Thrown at agent/src/channels/feishu.py:503

            f"Supported: {methods}"
        )


def _begin_registration(domain: str = "feishu") -> dict:
    """Start the device-code flow. Returns device_code, qr_url, interval, expire_in."""
    base_url = _accounts_base_url(domain)
    res = _post_registration(base_url, {
        "action": "begin",
        "archetype": "PersonalAgent",
        "auth_method": "client_secret",
        "request_user_info": "open_id",
    })
    device_code = res.get("device_code")
    if not device_code:
        raise RuntimeError("Feishu / Lark registration did not return a device_code")
    qr_url = res.get("verification_uri_complete", "")
    if not qr_url:
        raise RuntimeError("Feishu / Lark registration did not return a login URL")
    return {
        "device_code": device_code,
        "qr_url": qr_url,
        "interval": res.get("interval") or 5,
        "expire_in": res.get("expire_in") or 600,
    }


def _poll_registration(
    *,
    device_code: str,
    interval: int,
    expire_in: int,
    domain: str = "feishu",
) -> dict | None:
    """Poll until the user scans the QR code, or timeout/denial.

    Returns dict with app_id, app_secret, domain on success, None on failure.

View on GitHub (pinned to 80ffdda44c)

Solutions

  1. Inspect the raw registration response (log res) to see the actual payload keys returned by your Feishu/Lark endpoint
  2. Verify the app credentials (app_id/app_secret) and that the app has the Device Code / QR login scope enabled in the Feishu open platform console
  3. Check whether you're hitting Feishu (open.feishu.cn) vs Lark (open.larksuite.com) and that the registration URL matches your app's region
  4. Fall back to verification_uri if verification_uri_complete is absent
  5. Upgrade vibe-trading-ai in case the field mapping was fixed for a newer API version

Example fix

// before
qr_url = res.get("verification_uri_complete", "")
if not qr_url:
    raise RuntimeError("Feishu / Lark registration did not return a login URL")

// after
qr_url = res.get("verification_uri_complete") or res.get("verification_uri", "")
if not qr_url:
    raise RuntimeError("Feishu / Lark registration did not return a login URL")
Defensive patterns

Strategy: try-catch

Validate before calling

null

Type guard

null

Try / catch

try:
    result = await channel._qr_register_inner()
except RuntimeError as e:
    if "login URL" in str(e):
        logger.error("feishu registration incomplete: %s", e)
        raise RegistrationIncomplete(str(e)) from e
    raise

Prevention

When it happens

Trigger: Calling the Feishu device-code registration endpoint (the call whose response is parsed into res) and receiving JSON with device_code set but verification_uri_complete missing, empty, or renamed. Only hit from _qr_register_inner during QR-based registration startup.

Common situations: Feishu/Lark API version changes renaming the field, regional Lark vs Feishu endpoints returning different payload shapes, app_id/app_key misconfiguration causing an error body that still includes a device_code-like field, or a proxy/gateway stripping fields.

Related errors


AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28). Data as JSON: /api/errors/021036d53b4bbf24. Report an issue: GitHub.