Skip to content

[Bug] All API calls timeout on WSL with HTTP proxy — custom httpx transport bypasses proxy env vars in general agent path #11609

@nana-0x01

Description

@nana-0x01

Summary

After updating past v2026.4.16, every API call fails with APITimeoutError on WSL2 environments using an HTTP(S) proxy (e.g. Clash TUN mode). The root cause is that Hermes injects a custom httpx.HTTPTransport for TCP keepalive, which causes httpx to silently ignore HTTPS_PROXY/HTTP_PROXY environment variables — the agent then attempts direct connections to API endpoints, which fail on WSL where all outbound traffic must go through the proxy.

Environment

  • OS: WSL2 Ubuntu on Windows 11
  • Proxy: Clash TUN mode (127.0.0.1:7897), injected via HTTPS_PROXY/HTTP_PROXY env vars
  • Hermes: v0.10.0 (v2026.4.16) is the last working version; any version after this breaks
  • Python: 3.10
  • Providers affected: all (OpenAI, Anthropic, OpenRouter, etc.)

Steps to Reproduce

  1. Run Hermes on WSL2 with an HTTP(S) proxy configured via environment variables
  2. Update to any version after v2026.4.16
  3. Try any API call (e.g. hermes chat)

Expected Behavior

API calls succeed, routed through the configured proxy.

Actual Behavior

Every API call times out after 3 retry attempts with APITimeoutError.

Root Cause Analysis

  1. _create_openai_client() in run_agent.py injects httpx.Client(transport=httpx.HTTPTransport(...)) for TCP keepalive
  2. When httpx receives a custom transport, it does not automatically configure proxy support from environment variables
  3. On WSL, direct connections to public API endpoints are blocked by network architecture — all traffic must route through the Clash TUN interface
  4. The TLS handshake hangs indefinitely because packets are dropped (no route without proxy)
  5. Result: APITimeoutError on every call

This is the same root cause as #11414, which fixed it for the Codex path specifically but left the general agent path (run_agent.py) unpatched.

Related Issues

  • #11414 — Fixed proxy bypass for Codex clients only
  • #11249 — httpx.Client shared/close bug (same _create_openai_client area)
  • #10324 — CLOSE-WAIT hangs with custom providers
  • #6403 — Malformed proxy env detection

Suggested Fix

Apply the same pattern as #11414 to the general agent path in run_agent.py:

import os

def _create_openai_client(self, client_kwargs, *, reason, shared):
    has_proxy = any(os.getenv(k) for k in ("HTTPS_PROXY", "HTTP_PROXY", "ALL_PROXY"))
    
    if "http_client" not in client_kwargs:
        if has_proxy:
            # Let httpx auto-detect proxy from env — skip custom transport
            pass  
        else:
            client_kwargs["http_client"] = httpx.Client(
                transport=httpx.HTTPTransport(keepalive_expiry=30)
            )
    
    return OpenAI(**client_kwargs)

Workaround

Roll back to v2026.4.16:

cd ~/.hermes/hermes-agent
hermes gateway stop
git checkout v2026.4.16
pip install . --quiet
hermes gateway restart

Why This Matters

WSL2 users who need a proxy for outbound access (common in China, corporate networks, etc.) cannot use any Hermes version after v2026.4.16. The fix is minimal (same approach as #11414) and non-breaking for users without proxies.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1High — major feature broken, no workaroundcomp/agentCore agent loop, run_agent.py, prompt buildersweeper:implemented-on-mainSweeper: behavior already present on current maintype/bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions