langchain-ai/deepagents · error · RuntimeError

Authorization denied by provider: {err_code}{detail}

Error message

Authorization denied by provider: {err_code}{detail}

What it means

_parse_callback_url inspects the OAuth redirect query string; if the provider returned an `error` parameter (RFC 6749 error responses such as access_denied), the code raises RuntimeError including the error code and optional error_description. This means the authorization server (or user) denied the grant rather than the callback being malformed.

Source

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

def _parse_callback_url(url: str) -> tuple[str, str | None]:
    """Parse a provider callback URL into `(code, state)`.

    Args:
        url: Raw callback URL pasted by the user.

    Returns:
        The `code` and optional `state` query parameters.

    Raises:
        RuntimeError: If the URL contains `error=` or lacks `code`.
    """
    params = parse_qs(urlparse(url).query)
    if "error" in params:
        err_code = params["error"][0]
        err_desc = (params.get("error_description") or [""])[0]
        detail = f": {err_desc}" if err_desc else ""
        msg = f"Authorization denied by provider: {err_code}{detail}"
        raise RuntimeError(msg)
    if "code" not in params or not params["code"]:
        msg = "Callback URL is missing the 'code' parameter."
        raise RuntimeError(msg)
    return params["code"][0], (params.get("state") or [None])[0]


def _default_ui() -> OAuthInteraction:
    """Return the default `OAuthInteraction` implementation (CLI stdio)."""
    from deepagents_code.mcp_oauth_ui import CliOAuthInteraction

    return CliOAuthInteraction()


def _make_loopback_handlers(
    *,
    callback_server: _LoopbackOAuthCallbackServer,
    extra_auth_params: dict[str, str] | None = None,
    ui: OAuthInteraction | None = None,

View on GitHub (pinned to a1af029e6e)

Solutions

  1. Read the err_code/description in the message (e.g. access_denied) and retry the login, approving the consent screen this time.
  2. Request/enable the missing scopes on the OAuth application if the description names them.
  3. If access_denied is unexpected, check org/app restrictions (allowed users, verified-app status) on the provider dashboard and retry `/mcp login <server>`.

Example fix

// before (provider consent denied)
https://localhost:port/callback?error=access_denied&error_description=The+user+has+denied+your+application
// after
retry: /mcp login github  # then click 'Authorize' on the consent screen
Defensive patterns

Strategy: try-catch

Validate before calling

# validate the OAuth app config up front
for scope in required_scopes:
    assert scope in app_registered_scopes, f"scope {scope} not granted to OAuth app"

Try / catch

try:
    code, state = _parse_callback_url(url)
except RuntimeError as e:
    if str(e).startswith("Authorization denied by provider"):
        show_user("Consent was denied or the app lacks scopes; approve the request and retry `/mcp login`.")
    else:
        raise

Prevention

When it happens

Trigger: The browser redirect lands on the callback URL with ?error=... (optionally &error_description=...) during any paste-back/local-callback OAuth flow; raised from callback via _parse_callback_url.

Common situations: User clicked 'Cancel'/'Deny' on the provider consent screen, the OAuth app lacks required scopes so the provider rejects, provider-side policy blocks the app (unverified app, org restrictions), or account mismatch (logged into wrong account).

Related errors


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