oraios/serena · critical · ConnectionError
ProjectServer is not reachable at {self._base_url}. Make sur
Error message
ProjectServer is not reachable at {self._base_url}. Make sure the server is running. What it means
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.
Source
Thrown at src/serena/project_server.py:173
by sending a heartbeat request. If the server is not running, a
:class:`ConnectionError` is raised.
"""
def __init__(self, host: str = "127.0.0.1", port: int = ProjectServer.PORT, timeout: int = 300) -> None:
"""
:param host: the host address of the project server.
:param port: the port of the project server.
:raises ConnectionError: if the project server is not reachable.
"""
self._base_url = f"http://{host}:{port}"
self._timeout = timeout
# verify that the server is running
try:
response = requests_lib.get(f"{self._base_url}/heartbeat", timeout=5)
response.raise_for_status()
except requests_lib.ConnectionError:
raise ConnectionError(f"ProjectServer is not reachable at {self._base_url}. Make sure the server is running.")
except requests_lib.RequestException as e:
raise ConnectionError(f"ProjectServer health check failed: {e}")
def query_project(self, project_name: str, tool_name: str, tool_params_json: str) -> str:
"""
Query a project by executing a Serena tool in its context.
The interface matches :meth:`QueryProjectTool.apply
<serena.tools.query_project_tools.QueryProjectTool.apply>`.
:param project_name: the name of the project to query.
:param tool_name: the name of the tool to execute. The tool must be read-only.
:param tool_params_json: the parameters to pass to the tool, encoded as a JSON string.
:return: the tool's result as a string.
"""
payload = QueryProjectRequest(
project_name=project_name,
tool_name=tool_name,View on GitHub (pinned to 7fcbca7e62)
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
Example fix
// before
client = ProjectServerClient("http://localhost:24282") # server not started
// after
subprocess.Popen(["serena-project-server", "--port", "24282"])
wait_for_heartbeat("http://localhost:24282/heartbeat")
client = ProjectServerClient("http://localhost:24282") Defensive patterns
Strategy: retry
Validate before calling
import requests
def server_up(url: str) -> bool:
try:
return requests.get(f"{url}/heartbeat", timeout=5).ok
except requests.ConnectionError:
return False Try / catch
for attempt in range(5):
try:
return ProjectServerClient(base_url)
except ConnectionError:
time.sleep(2 ** attempt) # then start server if still down
raise RuntimeError("ProjectServer never became reachable") Prevention
- 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
When it happens
Trigger: 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).
Common situations: 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.
Related errors
- Failed to connect to Serena service at {url}: {e}
- No free ports found starting from {start_port}
- Found no Serena service in a JetBrains IDE instance for the
- Request to {url} timed out: {e}
- API request failed with HTTP error: {e}
AI-assisted analysis of oraios/serena@7fcbca7e62 (2026-08-29).
Data as JSON: /api/errors/ad0f91db108019b1.
Report an issue: GitHub.