{"record":{"id":"ad0f91db108019b1","repo":"oraios/serena","slug":"projectserver-is-not-reachable-at-self-base-url","errorCode":null,"errorMessage":"ProjectServer is not reachable at {self._base_url}. Make sure the server is running.","messagePattern":"ProjectServer is not reachable at (.+?)\\. Make sure the server is running\\.","errorType":"exception","errorClass":"ConnectionError","httpStatus":null,"severity":"critical","filePath":"src/serena/project_server.py","lineNumber":173,"sourceCode":"    by sending a heartbeat request. If the server is not running, a\n    :class:`ConnectionError` is raised.\n    \"\"\"\n\n    def __init__(self, host: str = \"127.0.0.1\", port: int = ProjectServer.PORT, timeout: int = 300) -> None:\n        \"\"\"\n        :param host: the host address of the project server.\n        :param port: the port of the project server.\n        :raises ConnectionError: if the project server is not reachable.\n        \"\"\"\n        self._base_url = f\"http://{host}:{port}\"\n        self._timeout = timeout\n\n        # verify that the server is running\n        try:\n            response = requests_lib.get(f\"{self._base_url}/heartbeat\", timeout=5)\n            response.raise_for_status()\n        except requests_lib.ConnectionError:\n            raise ConnectionError(f\"ProjectServer is not reachable at {self._base_url}. Make sure the server is running.\")\n        except requests_lib.RequestException as e:\n            raise ConnectionError(f\"ProjectServer health check failed: {e}\")\n\n    def query_project(self, project_name: str, tool_name: str, tool_params_json: str) -> str:\n        \"\"\"\n        Query a project by executing a Serena tool in its context.\n\n        The interface matches :meth:`QueryProjectTool.apply\n        <serena.tools.query_project_tools.QueryProjectTool.apply>`.\n\n        :param project_name: the name of the project to query.\n        :param tool_name: the name of the tool to execute. The tool must be read-only.\n        :param tool_params_json: the parameters to pass to the tool, encoded as a JSON string.\n        :return: the tool's result as a string.\n        \"\"\"\n        payload = QueryProjectRequest(\n            project_name=project_name,\n            tool_name=tool_name,","sourceCodeStart":155,"sourceCodeEnd":191,"githubUrl":"https://github.com/oraios/serena/blob/7fcbca7e62555ec2287ddb2f083caee805848ea6/src/serena/project_server.py#L155-L191","documentation":"ProjectServerClient's constructor performs a /heartbeat GET with a 5s timeout to verify the server is up. A requests.ConnectionError means nothing is listening at the configured base URL, so construction is aborted with a ConnectionError.","triggerScenarios":"Instantiating the client before the ProjectServer process was started; wrong host/port in the base URL; server crashed or firewall blocks the port; server still starting up (slow boot exceeding implicit connect).","commonSituations":"Forgetting to run the ProjectServer entrypoint in scripts/CI; Docker containers where the server binds to localhost inside the container; port collisions changed the actual listening port.","solutions":["Start the ProjectServer process and wait for it to log that it is listening before creating the client","Verify the base_url host/port match the server's actual bind address (use 0.0.0.0/actual container IP in Docker)","Check that nothing (firewall, VPN, port conflict) blocks the port and re-run"],"exampleFix":"// before\nclient = ProjectServerClient(\"http://localhost:24282\")  # server not started\n// after\nsubprocess.Popen([\"serena-project-server\", \"--port\", \"24282\"])\nwait_for_heartbeat(\"http://localhost:24282/heartbeat\")\nclient = ProjectServerClient(\"http://localhost:24282\")","handlingStrategy":"retry","validationCode":"import requests\ndef server_up(url: str) -> bool:\n    try:\n        return requests.get(f\"{url}/heartbeat\", timeout=5).ok\n    except requests.ConnectionError:\n        return False","typeGuard":null,"tryCatchPattern":"for attempt in range(5):\n    try:\n        return ProjectServerClient(base_url)\n    except ConnectionError:\n        time.sleep(2 ** attempt)  # then start server if still down\nraise RuntimeError(\"ProjectServer never became reachable\")","preventionTips":["Start the ProjectServer and wait for its listening log before constructing clients","Health-check the /heartbeat endpoint in deployment scripts","Use the correct host/port; in Docker bind and connect via the container's reachable address"],"tags":["network","connection","server"],"backgroundTag":"connection-refused","analyzedSha":"7fcbca7e62555ec2287ddb2f083caee805848ea6","analyzedAt":"2026-08-29T00:04:09.619Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}