langchain-ai/deepagents · error · RuntimeError

Token response from {token_url} is not a valid OAuth token p

Error message

Token response from {token_url} is not a valid OAuth token payload: {exc}

What it means

`_run_device_flow` raises this RuntimeError when the token endpoint responds HTTP 200 but the JSON body does not match the `OAuthToken` pydantic schema (missing/invalid `access_token`, `token_type`, or `expires_in` fields). This guards against APIs or proxies returning unexpected payloads.

Source

Thrown at libs/code/deepagents_code/mcp_auth.py:1979

            if err:
                msg = f"Device flow failed: {err}: {body.get('error_description', '')}"
                raise RuntimeError(msg)
            try:
                token_response.raise_for_status()
            except httpx.HTTPStatusError as exc:
                msg = (
                    f"Token request failed: HTTP {token_response.status_code} "
                    f"from {token_url}."
                )
                raise RuntimeError(msg) from exc
            try:
                return OAuthToken.model_validate(body)
            except ValidationError as exc:
                msg = (
                    f"Token response from {token_url} is not a valid "
                    f"OAuth token payload: {exc}"
                )
                raise RuntimeError(msg) from exc

    msg = "Device flow timed out. Try logging in again."
    raise RuntimeError(msg)


def format_login_failure(exc: BaseException) -> str:
    """Return a token-safe single-line summary of an OAuth-login exception.

    OAuth handshakes commonly surface as `ExceptionGroup` (anyio task
    groups) or as MCP-SDK errors whose `args`/`repr` may include an
    `OAuthToken`. Never call `str()`/`repr()` on the raw exception for
    display or logging — instead, prefer a known-safe nested
    `MCPReauthRequiredError` message, fall back to the messages of our
    own loopback-related exception types, and degrade to a class-name
    chain for anything else.

    Args:
        exc: Root exception caught from the login worker.

View on GitHub (pinned to a1af029e6e)

Solutions

  1. Inspect the pydantic ValidationError detail in the message to see which field is missing or mistyped
  2. Confirm you are hitting the real GitHub token endpoint and not a proxy/captive portal returning HTML
  3. If using a custom base URL or enterprise instance, verify its token response matches the standard OAuth token schema
  4. Update the package if GitHub's payload shape changed and a newer version handles it

Example fix

// before: custom endpoint returning non-OAuth JSON
"github_api_url": "https://internal-mock/api"  // returns {"ok": true}
// after
"github_api_url": "https://github.com"  // returns {"access_token", "token_type", ...}
Defensive patterns

Strategy: try-catch

Validate before calling

# Ensure no proxy/portal intercepts responses with HTML
import httpx
resp = httpx.get("https://github.com", follow_redirects=True)
if "text/html" in resp.headers.get("content-type", "") and "<html" in resp.text[:200].lower():
    print("Warning: an intercepting proxy or captive portal is rewriting responses")

Try / catch

try:
    login(server_name)
except RuntimeError as exc:
    if "not a valid OAuth token payload" in str(exc):
        print("Token endpoint returned unexpected JSON. Check proxy, captive portal, or custom base URL:", exc)
    raise

Prevention

When it happens

Trigger: A successful-status response whose body lacks the required OAuth token fields — e.g. an authentication proxy returns an HTML login page with 200, or a base-URL override points at a server returning a different JSON shape.

Common situations: Captive portals or SSO gateways injecting HTML into responses; a mocked/stubbed GitHub-compatible endpoint returning partial fields; schema drift when pointing at a self-hosted or enterprise instance; an intermediary stripping response fields.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29). Data as JSON: /api/errors/c891a64be2a07c55. Report an issue: GitHub.