oraios/serena · error · SerenaClientError
Request failed: {e}
Error message
Request failed: {e} What it means
The final catch-all in _make_request: any other requests.exceptions.RequestException (not ConnectionError/Timeout/HTTPError — e.g. TooManyRedirects, ChunkedEncodingError, InvalidURL) is re-raised as SerenaClientError('Request failed: {e}').
Source
Thrown at src/serena/jetbrains/jetbrains_plugin_client.py:359
raise ConnectionError(f"Failed to connect to Serena service at {url}: {e}")
except requests.exceptions.Timeout as e:
raise ConnectionError(f"Request to {url} timed out: {e}")
except requests.exceptions.HTTPError as e:
if response is not None:
# check for recoverable error (i.e. errors where the problem can be resolved by the caller or
# other errors where the error text shall simply be passed on to the LLM).
# The plugin returns 400 for such errors (typically illegal arguments, e.g. non-unique name path)
# but only since version 2023.2.6
if self.is_version_at_least(2023, 2, 6):
is_recoverable_error = response.status_code == 400
else:
is_recoverable_error = True # assume recoverable for older versions (mix of errors)
if is_recoverable_error:
raise APIError(response)
raise PluginServerError(f"API request failed with status {response.status_code}: {response.text}")
raise PluginServerError(f"API request failed with HTTP error: {e}")
except requests.exceptions.RequestException as e:
raise SerenaClientError(f"Request failed: {e}")
@staticmethod
def _pythonify_response(response: T) -> T:
"""
Converts dictionary keys from camelCase to snake_case recursively.
:response: the response in which to convert keys (dictionary or list)
"""
to_snake_case = lambda s: "".join(["_" + c.lower() if c.isupper() else c for c in s])
def convert(x):
if isinstance(x, dict):
return {to_snake_case(k): convert(v) for k, v in x.items()}
elif isinstance(x, list):
return [convert(item) for item in x]
else:
return x
View on GitHub (pinned to 7fcbca7e62)
Solutions
- Inspect the wrapped exception message for the underlying cause
- Re-run from_project to rediscover a valid service URL
- Fix proxy environment variables affecting localhost
- Restart the IDE and retry the operation
Defensive patterns
Strategy: try-catch
Validate before calling
# validate the discovered service URL before use
from urllib.parse import urlparse
def valid_service_url(url: str) -> bool:
p = urlparse(url)
return p.scheme in ("http", "https") and bool(p.hostname) and p.port is not None Try / catch
try:
client = JetBrainsPluginClient.from_project(project)
refs = client.find_references(name_path="Foo")
except SerenaClientError as e:
if "Request failed" in str(e):
log.error("Underlying requests error: %s — rediscover service and retry", e)
client = JetBrainsPluginClient.from_project(project)
else:
raise Prevention
- Inspect the wrapped cause in the message (InvalidURL, TooManyRedirects, etc.)
- Fix proxy/redirect env settings for localhost traffic
- Rediscover the service URL after IDE restarts
- Catch SerenaClientError as the umbrella type for all plugin client failures
When it happens
Trigger: Unusual requests-library failures during plugin API calls — malformed service URL, too many redirects, response decoding errors — from client init or symbol/reference operations.
Common situations: Bad discovered service URL (whitespace/garbage port); proxy misconfiguration; interrupted local HTTP stream when the IDE is killed mid-response.
Related errors
- Failed to connect to Serena service at {url}: {e}
- Request to {url} timed out: {e}
- API request failed with HTTP error: {e}
- API request failed with status {response.status_code}: {resp
- ProjectServer health check failed: {e}
AI-assisted analysis of oraios/serena@7fcbca7e62 (2026-08-29).
Data as JSON: /api/errors/1e10740b1cbff197.
Report an issue: GitHub.