oraios/serena · error · PluginServerError
API request failed with HTTP error: {e}
Error message
API request failed with HTTP error: {e} What it means
When requests raises an HTTPError but the response object is unavailable (response is None), _make_request raises PluginServerError('API request failed with HTTP error: {e}') — the request failed at HTTP level without a usable response body to inspect or classify as recoverable.
Source
Thrown at src/serena/jetbrains/jetbrains_plugin_client.py:357
except requests.exceptions.ConnectionError as e:
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:View on GitHub (pinned to 7fcbca7e62)
Solutions
- Retry the request; transient connection drops resolve after the plugin service settles
- Restart the IDE/plugin service if it recurs
- Check proxy/localhost networking as in connection errors
- Update the plugin and client to matched versions
Defensive patterns
Strategy: try-catch
Try / catch
try:
overview = client.get_symbols_overview(relative_path="src")
except (PluginServerError, ConnectionError) as e:
log.warning("Plugin request failed (%s); retrying once", e)
overview = retry_once(lambda: client.get_symbols_overview(relative_path="src")) Prevention
- Add one retry for transient plugin-request failures
- Verify proxy/localhost networking configuration
- Update plugin + client together to reduce protocol mismatches
- Restart the IDE if failures repeat
When it happens
Trigger: HTTP-level failure where response was never assigned/available in the except block, e.g. errors raised before a response was fully received; typically seen from the same callers (init, find_symbol, move, find_references, get_symbols_overview, get_supertypes).
Common situations: Malformed responses/connection drops mid-exchange; plugin service restarting between connect and response; unusual proxy behavior.
Understand the failure class
Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.
Related errors
- Failed to connect to Serena service at {url}: {e}
- Request to {url} timed out: {e}
- API request failed with status {response.status_code}: {resp
- Request failed: {e}
- ProjectServer health check failed: {e}
AI-assisted analysis of oraios/serena@7fcbca7e62 (2026-08-29).
Data as JSON: /api/errors/c840ec32ff506084.
Report an issue: GitHub.