When I use openhands CLI with openrouter, it alway...
# questions
r
When I use openhands CLI with openrouter, it always return to me the error message as follow, even if I only ask with the prompt
Create a Python script that prints "Hello, World!"
Can I have any support from you. 🙂 Conversation Error Code: APIError Detail: litellm.APIError: APIError: OpenrouterException - \[SSL: UNEXPECTED_EOF_WHILE_READING\] EOF occurred in violation of protocol (_ssl.c:1000)
g
can you share how you set up your LLM? i suspect it might have to do with your base URL
r
I set up with option advance; set the base url as
<https://openrouter.ai/api/v1>
and the model as
openrouter/openai/gpt-oss-120b:free
I also tried to test the connection to openrouter with the command
curl -v <https://openrouter.ai/v1/health1>
it returns 200 and works well. Now, it sometimes return the message "litellm.APIError: APIError: OpenrouterException - Server disconnected without sending a response." as follows
Copy code
Conversation Error
Code: APIError
Detail:
litellm.APIError: APIError: OpenrouterException - Server disconnected without sending a response.
Any suggestions? Thanks.
g
@nutritious-balloon-65098 why is this user getting a litellm error but passing an openrouter url? How can this user fix this?
n
I'm on it! Jamie can track my progress here.
The user can “pass” an OpenRouter URL (e.g., a basic
curl
health check returning 200) and still get LiteLLM
OpenrouterException
errors because those errors are caused by the connection being closed mid-request on the actual OpenAI-compatible chat endpoint (`POST https://openrouter.ai/api/v1/chat/completions`), not by simple reachability. In practice this is commonly due to (a) OpenRouter or the underlying routed provider dropping/aborting connections (especially on
:free
routes under load), (b) differences between
curl
and Python’s TLS/HTTP stack (httpx/ssl) interacting with proxies, IPv6, or TLS inspection, and/or (c) request characteristics like streaming/tool-calling payloads that stress the route more than a health check. How the user can fix it: • Test the real endpoint with curl (a minimal
/chat/completions
POST with their API key) to confirm whether the disconnect reproduces outside OpenHands. • Switch to a different (preferably non-
:free
) model/route
to improve stability; intermittent EOF/disconnect errors are often capacity/route issues. • Verify they’re using LiteLLM’s OpenRouter format (
model="openrouter/<provider>/<model>"
, base URL `https://openrouter.ai/api/v1`) per LiteLLM docs. • Check OpenRouter status for chat completions. • If on a corporate/proxied network, fix Python trust/CA/proxy settings (TLS inspection can break Python even when curl works), using LiteLLM/HTTPX SSL guidance as needed. No code changes were made; I only investigated the repo configuration paths and referenced LiteLLM’s OpenRouter documentation to support the explanation.
The user is getting LiteLLM
OpenrouterException
errors (
SSL: UNEXPECTED_EOF_WHILE_READING
/ “Server disconnected without sending a response”) even though a simple
curl
health check returns
200
because the health check is not exercising the same endpoint, request type, or load pattern as the OpenHands CLI call. OpenHands (via LiteLLM) is making real
POST <https://openrouter.ai/api/v1/chat/completions>
requests (often larger payloads, tool-calling, sometimes streaming), and those can be intermittently dropped by OpenRouter, the upstream provider OpenRouter routed to (especially for
:free
routes / large models), or by a network proxy/VPN/middlebox that affects Python/httpx differently than curl. Workarounds to get it working in the CLI: • Verify the real endpoint with curl (POST
/api/v1/chat/completions
), not a health URL, to confirm whether disconnects happen outside the CLI too. • Switch away from
openai/gpt-oss-120b:free
/
:free
routes
(try a different model, preferably non-free, or a smaller model) to avoid unstable capacity/routing. • Eliminate proxy/VPN effects by unsetting
HTTP_PROXY/HTTPS_PROXY/ALL_PROXY
and setting
NO_PROXY=<http://openrouter.ai|openrouter.ai>
, then restarting the CLI. • Optionally set OpenRouter identity headers via env vars (
OR_SITE_URL
,
OR_APP_NAME
) and restart. • If using headless mode, a crude but effective workaround is to retry the CLI run in a shell loop until it succeeds. • The “proper” reliability solution is to put a retrying proxy in front (e.g., LiteLLM Proxy with retries/fallbacks) and point OpenHands at that local proxy; alternatively, OpenHands CLI could be improved by adding built-in retries for these transient disconnect errors (no code changes were made in this session).
g
Can you try another model and see if it'll work @rich-area-58708 ty
r
No, not at all. I tried several different models, including free and paid ones. I believe that is related to my VPN. Thanks for your help.
👍 1