calesthio/OpenMontage · error · RuntimeError

Non-JSON response from TokenHub API: HTTP {response.status_c

Error message

Non-JSON response from TokenHub API: HTTP {response.status_code}

What it means

RuntimeError from _json_or_raise when a TokenHub HTTP response body cannot be parsed as JSON (requests raises ValueError internally). It typically indicates a non-200 status with an HTML/text error page, or a gateway/CDN intercepting the request, rather than an API-level error.

Source

Thrown at tools/graphics/hunyuan_image.py:545

    # ------------------------------------------------------------------

    @staticmethod
    def _safe_error(exc: Exception) -> str:
        """Redact secret values from exception messages."""
        msg = str(exc)
        for var in ("TENCENT_TOKENHUB_API_KEY",):
            val = os.environ.get(var, "")
            if val:
                msg = msg.replace(val, "[redacted]")
        return msg

    @staticmethod
    def _json_or_raise(response: Any) -> dict[str, Any]:
        """Parse JSON response body or raise with HTTP status."""
        try:
            return response.json()
        except ValueError as exc:
            raise RuntimeError(
                f"Non-JSON response from TokenHub API: HTTP {response.status_code}"
            ) from exc

    @staticmethod
    def _check_response(payload: dict[str, Any]) -> None:
        """Check the TokenHub API response for errors.

        TokenHub returns errors at the top level with an ``error`` field.
        """
        error = payload.get("error")
        if error:
            message = error.get("message", "unknown error")
            code = error.get("code", error.get("type", "unknown"))
            raise RuntimeError(
                f"TokenHub API error: code={code}, message={message}"
            )

    # ------------------------------------------------------------------

View on GitHub (pinned to 95e1c3d0ab)

Solutions

  1. Inspect response.status_code (it is in the message) and the raw body (response.text) to identify the interceptor
  2. Verify TENCENT_TOKENHUB_API_KEY is set, valid, and has TokenHub entitlements
  3. Confirm the API host/path constants match the documented TokenHub endpoint for your region
  4. Retry transient 5xx gateway errors after a short backoff
Defensive patterns

Strategy: retry

Try / catch

try:
    data = client._json_or_raise(resp)
except RuntimeError as e:
    if "Non-JSON" in str(e):
        status = resp.status_code
        if status >= 500:
            time.sleep(2 ** attempt)  # gateway hiccup: back off and retry
        else:
            raise  # 4xx HTML page = auth/proxy/config problem, not retryable

Prevention

When it happens

Trigger: Expired or invalid API key causing an auth proxy to return an HTML 401/403 page; Cloudflare-style challenge pages; wrong _HOST value hitting a non-API server; rate-limit responses with plain-text bodies; transient 502/504 HTML from load balancers.

Common situations: TENCENT_TOKENHUB_API_KEY not set or expired; corporate proxy or VPN mangling responses; regional endpoint hostname misconfigured; scraping a status page instead of the API host.

Related errors


AI-assisted analysis of calesthio/OpenMontage@95e1c3d0ab (2026-08-15). Data as JSON: /api/errors/fec67e7d92685d20. Report an issue: GitHub.