ZhuLinsen/daily_stock_analysis · error · RuntimeError

OAuth token 缓存已失效或缺失,当前为无头运行不支持打开授权页面,请重建 LONGBRIDGE_OAUTH_T

Error message

OAuth token 缓存已失效或缺失,当前为无头运行不支持打开授权页面,请重建 LONGBRIDGE_OAUTH_TOKEN_CACHE_B64: {url}

What it means

RuntimeError from the Longbridge OAuth path: the LONGBRIDGE_OAUTH_TOKEN_CACHE_B64 cache is missing, expired, or malformed, and re-authorization requires opening a browser page — impossible in the current headless run. The URL in the message is the auth page that cannot be opened; the cache must be rebuilt on a machine with a browser.

Source

Thrown at data_provider/longbridge_fetcher.py:313

    except UnicodeDecodeError as exc:
        logger.warning("[Longbridge] OAuth token 缓存不是 UTF-8 文本: %s", exc)
        return False

    try:
        data = json.loads(payload)
    except json.JSONDecodeError as exc:
        logger.warning("[Longbridge] OAuth token 缓存不是合法 JSON: %s", exc)
        return False

    if not isinstance(data, dict) or not data:
        logger.warning("[Longbridge] OAuth token 缓存内容为空或格式不符合预期: %s", token_cache)
        return False

    return True


def _oauth_reauth_not_supported(url: str) -> None:
    raise RuntimeError(
        f"OAuth token 缓存已失效或缺失,当前为无头运行不支持打开授权页面,请重建 LONGBRIDGE_OAUTH_TOKEN_CACHE_B64: {url}"
    )


def _oauth_sdk_unavailable_error() -> RuntimeError:
    return RuntimeError(
        "当前安装的 longbridge SDK 不支持 OAuth 2.0(缺少 OAuthBuilder/Config.from_oauth)。"
        "请在支持该 SDK 版本的平台安装 longbridge>=4.0.0,或继续使用 Legacy 三件套。"
    )


def _longbridge_credentials(config: Any = None) -> Dict[str, Optional[str]]:
    """Collect Longbridge auth inputs from Config/env without exposing secrets."""
    app_key = _clean_optional(getattr(config, "longbridge_app_key", None))
    app_secret = _clean_optional(getattr(config, "longbridge_app_secret", None))
    access_token = _clean_optional(getattr(config, "longbridge_access_token", None))
    oauth_client_id = _clean_optional(getattr(config, "longbridge_oauth_client_id", None))

View on GitHub (pinned to 5159bd72e8)

Solutions

  1. On a desktop with a browser, run the interactive Longbridge OAuth flow to mint a fresh token cache, base64-encode it, and set LONGBRIDGE_OAUTH_TOKEN_CACHE_B64 in the headless environment.
  2. Validate the cache before deploying: it must be valid JSON, a non-empty dict (the _validate logic above checks this).
  3. Alternative: fall back to the Legacy credential triple (app key/secret/access token) if OAuth is not required, or install a longbridge version matching the supported path.

Example fix

# headless machine
export LONGBRIDGE_OAUTH_TOKEN_CACHE_B64=$(base64 -w0 token_cache.json)
Defensive patterns

Strategy: validation

Validate before calling

import base64, json, os
cache_b64 = os.getenv('LONGBRIDGE_OAUTH_TOKEN_CACHE_B64', '')
try:
    data = json.loads(base64.b64decode(cache_b64)) if cache_b64 else None
    token_ok = isinstance(data, dict) and bool(data)
except Exception:
    token_ok = False
if not token_ok:
    logger.error('Longbridge OAuth cache invalid — regenerate on a desktop host')

Type guard

def longbridge_oauth_cache_valid() -> bool:
    b64 = os.getenv('LONGBRIDGE_OAUTH_TOKEN_CACHE_B64', '')
    try:
        d = json.loads(base64.b64decode(b64)) if b64 else None
        return isinstance(d, dict) and bool(d)
    except Exception:
        return False

Try / catch

try:
    df = longbridge.get_daily_data(code, ...)
except RuntimeError as e:
    if 'LONGBRIDGE_OAUTH_TOKEN_CACHE_B64' in str(e):
        disable_source('longbridge')  # headless re-auth impossible; use legacy creds or skip

Prevention

When it happens

Trigger: Running LongbridgeFetcher on a server/CI/container where the cached OAuth token (env var LONGBRIDGE_OAUTH_TOKEN_CACHE_B64) is absent or has expired (refresh token invalid), and _oauth_reauth_not_supported fires instead of launching the OAuth flow.

Common situations: Deploying to Docker/GitHub Actions with stale or forgotten token env; token expired since last interactive login; JSON corrupted (the code also warns on JSONDecodeError / empty dict just above); SDK >=4.0.0 with OAuthBuilder on a headless host.

Related errors


AI-assisted analysis of ZhuLinsen/daily_stock_analysis@5159bd72e8 (2026-08-15). Data as JSON: /api/errors/62425b53ffc4d9a4. Report an issue: GitHub.