langchain-ai/deepagents · error · RuntimeError
Device flow timed out. Try logging in again.
Error message
Device flow timed out. Try logging in again.
What it means
`_run_device_flow` gives up and raises this RuntimeError when the polling loop exhausts its time budget without ever receiving a terminal success or error response — the token poll kept returning `authorization_pending` (or `slow_down`) until the deadline. It is the normal failure mode when the user never completes the browser authorization in time.
Source
Thrown at libs/code/deepagents_code/mcp_auth.py:1982
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.
Returns:
A user-displayable string that is safe to log and to render.View on GitHub (pinned to a1af029e6e)
Solutions
- Re-run the login and complete the browser authorization promptly within the timeout window
- Ensure the verification URL is openable in your default browser (check BROWSER env var or open the printed URL manually)
- In headless/SSH environments, copy the code and URL to a machine with a browser
- Retry the login to get a fresh device code if the previous one expired
Example fix
// before: never opening the printed verification URL $ dcode mcp login Device code: ABCD-1234 # ignore, flow times out // after $ dcode mcp login # open https://github.com/login/device immediately and enter ABCD-1234
Defensive patterns
Strategy: retry
Validate before calling
# Verify a browser can open the verification URL before starting login
import webbrowser
if not webbrowser.get():
print("No browser available; copy the device-code URL to another machine") Try / catch
try:
login(server_name)
except RuntimeError as exc:
if "Device flow timed out" in str(exc):
print("Authorization not completed in time. Re-run login and approve promptly.")
login(server_name) # fresh device code
raise Prevention
- Start the login only when ready to confirm in the browser immediately
- Open the verification URL manually if the default browser does not launch
- In headless environments, forward the code/URL to an interactive machine first
When it happens
Trigger: The device-flow poll loop runs past its timeout while the user has not yet opened the verification URL and entered the code; the loop exits its `while` and hits the unconditional raise at the end of the function.
Common situations: User ignored the browser prompt; verification URL blocked by browser policy; user entered the code after it expired without noticing; headless/CI environment where no one can complete the interactive step.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- Device flow failed: {err}: {body.get('error_description', ''
- Device code request failed: HTTP {response.status_code} from
- Device code response from {device_code_url} is missing requi
- Token request failed: HTTP {token_response.status_code} from
- Token response from {token_url} is not a valid OAuth token p
AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29).
Data as JSON: /api/errors/2d401453d2c781b0.
Report an issue: GitHub.