{"record":{"id":"4a1438ec9cac81a0","repo":"langchain-ai/deepagents","slug":"server-did-not-become-healthy-within-timeout-s","errorCode":null,"errorMessage":"Server did not become healthy within {timeout}s","messagePattern":"Server did not become healthy within (.+?)s","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"critical","filePath":"libs/code/deepagents_code/client/launch/server.py","lineNumber":355,"sourceCode":"            try:\n                resp = await client.get(health_url, timeout=2)\n                if resp.status_code == 200:  # noqa: PLR2004\n                    logger.info(\"Server is healthy at %s\", url)\n                    return\n                last_status = resp.status_code\n                logger.debug(\"Health check returned status %d\", resp.status_code)\n            except (httpx.TransportError, OSError) as exc:\n                logger.debug(\"Health check attempt failed: %s\", exc)\n                last_exc = exc\n\n            await asyncio.sleep(poll_interval)\n\n    msg = f\"Server did not become healthy within {timeout}s\"\n    if last_status is not None:\n        msg += f\" (last status: {last_status})\"\n    elif last_exc is not None:\n        msg += f\" (last error: {last_exc})\"\n    raise RuntimeError(msg)\n\n\n# ---------------------------------------------------------------------------\n# Server command / env construction\n# ---------------------------------------------------------------------------\n\n\ndef _build_server_cmd(config_path: Path, *, host: str, port: int) -> list[str]:\n    \"\"\"Build the `langgraph dev` command line.\n\n    Args:\n        config_path: Path to the `langgraph.json` config file.\n        host: Host to bind.\n        port: Port to bind.\n\n    Returns:\n        Command argv list.\n    \"\"\"","sourceCodeStart":337,"sourceCodeEnd":373,"githubUrl":"https://github.com/langchain-ai/deepagents/blob/a1af029e6e73cb17c36bff823d227747b28e91e1/libs/code/deepagents_code/client/launch/server.py#L337-L373","documentation":"`wait_for_server_healthy` polls the server's `/ok` health endpoint until a timeout expires; if the server never returns HTTP 200, it raises `RuntimeError` including the last HTTP status or connection exception for diagnosis.","triggerScenarios":"Server process is alive but never healthy within `timeout` seconds: slow startup (heavy imports/first-time dependency install), health endpoint bound to a different host/port than polled, server hung on startup, or firewall blocking loopback connections.","commonSituations":"Cold start with large dependency tree on slow machine, wrong host binding (server on 127.0.0.1, launcher polling another interface), port already occupied by another process answering slowly, or container networking issues.","solutions":["Increase the startup timeout to accommodate slow first boot","Check the appended `last status`/`last error` for whether the endpoint refused, 404'd, or hung","Confirm the server's bound host/port matches the launcher configuration","Inspect server logs for startup hangs (DB migrations, network calls) and fix the blocking step","Verify nothing else occupies the port and no firewall blocks localhost"],"exampleFix":"// before\nstart(timeout=30)  # slow cold boot exceeds 30s\n// after\nstart(timeout=120)  # allow time for first-time dependency install","handlingStrategy":"retry","validationCode":"import socket\nwith socket.socket() as s:\n    s.settimeout(2)\n    try:\n        s.connect((host, port))\n        print(\"port reachable\")\n    except OSError as e:\n        print(f\"endpoint unreachable before start: {e}\")","typeGuard":"def endpoint_pollable(host: str, port: int) -> bool:\n    import socket\n    try:\n        with socket.socket() as s:\n            s.settimeout(2)\n            s.connect((host, port))\n        return True\n    except OSError:\n        return False","tryCatchPattern":"try:\n    await wait_for_server_healthy(url, timeout=timeout)\nexcept RuntimeError as e:\n    if \"did not become healthy\" in str(e):\n        logger.warning(\"health timeout (%s); retrying with longer budget\", e)\n        await wait_for_server_healthy(url, timeout=timeout * 3)\n    else:\n        raise","preventionTips":["Set a generous timeout for cold starts / first-time installs","Ensure server bind host matches the polled health URL","Check the appended last-status/last-error to distinguish refused vs hanging","Monitor server logs for blocking startup work (migrations, network calls)"],"tags":["timeout","health-check","network"],"backgroundTag":"health-check-timeout","analyzedSha":"a1af029e6e73cb17c36bff823d227747b28e91e1","analyzedAt":"2026-08-29T11:43:24.718Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}