Skip to content

fix(telegram): pass proxy URL explicitly to HTTPXRequest when proxy env vars are set - #8931

Closed
MaybeRichard wants to merge 1 commit into
NousResearch:mainfrom
MaybeRichard:fix/telegram-explicit-proxy
Closed

fix(telegram): pass proxy URL explicitly to HTTPXRequest when proxy env vars are set#8931
MaybeRichard wants to merge 1 commit into
NousResearch:mainfrom
MaybeRichard:fix/telegram-explicit-proxy

Conversation

@MaybeRichard

Copy link
Copy Markdown
Contributor

Problem

When HTTPS_PROXY / HTTP_PROXY / ALL_PROXY env vars are set, the gateway correctly detects proxy_configured=True and skips the fallback-IP transport — but then creates HTTPXRequest(**request_kwargs) without an explicit proxy= argument, relying solely on httpx's trust_env mechanism.

In practice, trust_env alone is unreliable when the proxy is an HTTP CONNECT proxy (e.g. Clash / ClashMac in fake-ip mode, common for users in China): the TLS handshake inside the CONNECT tunnel fails intermittently via httpcore's anyio backend, even though the same proxy works fine from curl or requests/urllib3. The result is a flood of httpx.ConnectError / httpx.ConnectTimeout errors and failed message delivery.

Fix

When proxy_configured is True, read the proxy URL from the environment and pass it explicitly via HTTPXRequest(..., proxy=proxy_url). This matches the explicit approach already used in the aiohttp-based adapters (weixin/wecom/matrix, see #8680) and is more robust than trust_env for users behind HTTP CONNECT proxies.

# before
request = HTTPXRequest(**request_kwargs)
get_updates_request = HTTPXRequest(**request_kwargs)

# after
proxy_url = (
    os.getenv("HTTPS_PROXY") or os.getenv("https_proxy") or
    os.getenv("HTTP_PROXY") or os.getenv("http_proxy") or
    os.getenv("ALL_PROXY") or os.getenv("all_proxy")
)
request = HTTPXRequest(**request_kwargs, proxy=proxy_url)
get_updates_request = HTTPXRequest(**request_kwargs, proxy=proxy_url)

Test

Verified on macOS with ClashMac proxy (http://127.0.0.1:7890) in fake-ip mode. Before the fix: repeated ConnectError / TimedOut on polling and sends. After the fix: stable connection, messages delivered reliably.

🤖 Generated with Claude Code

…s configured

When HTTPS_PROXY/HTTP_PROXY/ALL_PROXY env vars are set, the code already
detects proxy_configured=True and skips the fallback-IP transport — but then
creates HTTPXRequest(**request_kwargs) without an explicit proxy, relying
solely on httpx's trust_env mechanism.

In practice, trust_env alone is unreliable for HTTP CONNECT proxies (e.g.
ClashMac / Clash in fake-ip mode): the TLS handshake performed inside the
CONNECT tunnel can fail intermittently when httpcore's anyio backend is used,
even though the same proxy works fine from curl or requests/urllib3.

Fix: when proxy_configured is True, read the proxy URL from the environment
and pass it explicitly via HTTPXRequest(..., proxy=proxy_url). This matches
the explicit approach used in the aiohttp adapters (weixin/wecom/matrix) and
is more robust than trust_env for users behind HTTP CONNECT proxies.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@MaybeRichard

Copy link
Copy Markdown
Contributor Author

The failing tests (test_telegram_photo_interrupts, test_session_hygiene, etc.) are pre-existing failures on origin/main — confirmed by running the same test suite against the upstream code before applying this PR's change. They are unrelated to the proxy fix.

The build-and-push failure is also a known flaky CI issue (npm install network timeout, exit code 254) that appears on main branch runs as well.

teknium1 pushed a commit that referenced this pull request Apr 13, 2026
…nv vars are set

When HTTPS_PROXY / HTTP_PROXY / ALL_PROXY env vars are set (or macOS system proxy
is detected), pass the proxy URL explicitly via HTTPXRequest(proxy=proxy_url) instead
of relying on httpx's trust_env mechanism, which is unreliable for HTTP CONNECT
proxies (e.g. Clash / ClashMac in fake-ip mode).

Uses the shared resolve_proxy_url() from base.py (handles env vars + macOS system
proxy detection) instead of duplicating env var reading inline. Consolidates the
proxy_configured boolean into a single proxy_url = resolve_proxy_url() call that
serves as both the gate for skipping fallback-IP transport and the value passed
to HTTPXRequest.

Co-authored-by: Hermes Agent <hermes@nousresearch.com>
Salvaged from PR #8931 by MaybeRichard.
teknium1 pushed a commit that referenced this pull request Apr 13, 2026
…nv vars are set

When HTTPS_PROXY / HTTP_PROXY / ALL_PROXY env vars are set (or macOS system proxy
is detected), pass the proxy URL explicitly via HTTPXRequest(proxy=proxy_url) instead
of relying on httpx's trust_env mechanism, which is unreliable for HTTP CONNECT
proxies (e.g. Clash / ClashMac in fake-ip mode).

Uses the shared resolve_proxy_url() from base.py (handles env vars + macOS system
proxy detection) instead of duplicating env var reading inline. Consolidates the
proxy_configured boolean into a single proxy_url = resolve_proxy_url() call that
serves as both the gate for skipping fallback-IP transport and the value passed
to HTTPXRequest.

Co-authored-by: Hermes Agent <hermes@nousresearch.com>
Salvaged from PR #8931 by MaybeRichard.
@teknium1

Copy link
Copy Markdown
Contributor

Merged via PR #8981. Your commit was cherry-picked onto current main with your authorship preserved in git log. Used the shared resolve_proxy_url() from base.py instead of inline env var reading (picks up macOS system proxy for free too). Thanks for the fix!

aj-nt pushed a commit to aj-nt/hermes-agent that referenced this pull request May 1, 2026
…nv vars are set

When HTTPS_PROXY / HTTP_PROXY / ALL_PROXY env vars are set (or macOS system proxy
is detected), pass the proxy URL explicitly via HTTPXRequest(proxy=proxy_url) instead
of relying on httpx's trust_env mechanism, which is unreliable for HTTP CONNECT
proxies (e.g. Clash / ClashMac in fake-ip mode).

Uses the shared resolve_proxy_url() from base.py (handles env vars + macOS system
proxy detection) instead of duplicating env var reading inline. Consolidates the
proxy_configured boolean into a single proxy_url = resolve_proxy_url() call that
serves as both the gate for skipping fallback-IP transport and the value passed
to HTTPXRequest.

Co-authored-by: Hermes Agent <hermes@nousresearch.com>
Salvaged from PR NousResearch#8931 by MaybeRichard.
02356abc pushed a commit to 02356abc/hermes-agent that referenced this pull request May 14, 2026
…nv vars are set

When HTTPS_PROXY / HTTP_PROXY / ALL_PROXY env vars are set (or macOS system proxy
is detected), pass the proxy URL explicitly via HTTPXRequest(proxy=proxy_url) instead
of relying on httpx's trust_env mechanism, which is unreliable for HTTP CONNECT
proxies (e.g. Clash / ClashMac in fake-ip mode).

Uses the shared resolve_proxy_url() from base.py (handles env vars + macOS system
proxy detection) instead of duplicating env var reading inline. Consolidates the
proxy_configured boolean into a single proxy_url = resolve_proxy_url() call that
serves as both the gate for skipping fallback-IP transport and the value passed
to HTTPXRequest.

Co-authored-by: Hermes Agent <hermes@nousresearch.com>
Salvaged from PR NousResearch#8931 by MaybeRichard.
gweeteve pushed a commit to gweeteve/hermes-agent that referenced this pull request Jun 2, 2026
…nv vars are set

When HTTPS_PROXY / HTTP_PROXY / ALL_PROXY env vars are set (or macOS system proxy
is detected), pass the proxy URL explicitly via HTTPXRequest(proxy=proxy_url) instead
of relying on httpx's trust_env mechanism, which is unreliable for HTTP CONNECT
proxies (e.g. Clash / ClashMac in fake-ip mode).

Uses the shared resolve_proxy_url() from base.py (handles env vars + macOS system
proxy detection) instead of duplicating env var reading inline. Consolidates the
proxy_configured boolean into a single proxy_url = resolve_proxy_url() call that
serves as both the gate for skipping fallback-IP transport and the value passed
to HTTPXRequest.

Co-authored-by: Hermes Agent <hermes@nousresearch.com>
Salvaged from PR NousResearch#8931 by MaybeRichard.
waefrebeorn pushed a commit to waefrebeorn/slermes that referenced this pull request Jul 2, 2026
…nv vars are set

When HTTPS_PROXY / HTTP_PROXY / ALL_PROXY env vars are set (or macOS system proxy
is detected), pass the proxy URL explicitly via HTTPXRequest(proxy=proxy_url) instead
of relying on httpx's trust_env mechanism, which is unreliable for HTTP CONNECT
proxies (e.g. Clash / ClashMac in fake-ip mode).

Uses the shared resolve_proxy_url() from base.py (handles env vars + macOS system
proxy detection) instead of duplicating env var reading inline. Consolidates the
proxy_configured boolean into a single proxy_url = resolve_proxy_url() call that
serves as both the gate for skipping fallback-IP transport and the value passed
to HTTPXRequest.

Co-authored-by: Hermes Agent <hermes@nousresearch.com>
Salvaged from PR NousResearch#8931 by MaybeRichard.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants