openclaw - ✅(Solved) Fix globalThis.fetch (undici) does not honor HTTP_PROXY/HTTPS_PROXY env vars [2 pull requests, 1 comments, 1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#62181Fetched 2026-04-08 03:07:58
View on GitHub
Comments
1
Participants
1
Timeline
6
Reactions
0
Author
Participants
Timeline (top)
cross-referenced ×4commented ×1subscribed ×1

globalThis.fetch (powered by undici) does not route through HTTP_PROXY/HTTPS_PROXY by default. This means any code path that uses globalThis.fetch or undici's fetch() directly bypasses the proxy entirely.

In proxy-only environments (like OpenShell sandboxes where all traffic must go through an HTTP CONNECT proxy at 10.200.0.1:3128), this causes LLM provider requests to fail silently or with connection errors — the requests attempt direct connections that the network namespace blocks.

Root Cause

globalThis.fetch (powered by undici) does not route through HTTP_PROXY/HTTPS_PROXY by default. This means any code path that uses globalThis.fetch or undici's fetch() directly bypasses the proxy entirely.

In proxy-only environments (like OpenShell sandboxes where all traffic must go through an HTTP CONNECT proxy at 10.200.0.1:3128), this causes LLM provider requests to fail silently or with connection errors — the requests attempt direct connections that the network namespace blocks.

Fix Action

Workaround

At Node.js startup (via NODE_OPTIONS=--require), manually set the global dispatcher:

const { EnvHttpProxyAgent, setGlobalDispatcher } = require('undici');
if (process.env.HTTPS_PROXY || process.env.HTTP_PROXY) {
  setGlobalDispatcher(new EnvHttpProxyAgent());
}

This makes all globalThis.fetch calls honor proxy env vars. We've been running this in production across 4 OpenShell sandboxes since 2026.4.5.

PR fix notes

PR #62241: fix(net): strip external undici dispatcher from custom fetchImpl calls

Description (problem / solution / changelog)

Summary

  • Fixes Slack file attachment downloads silently failing on OpenClaw 2026.4.5 with InvalidArgumentError: invalid onRequestStart method
  • Root cause: fetchWithSsrFGuard passes an external undici dispatcher (from the bundled undici package) through init to custom fetchImpl callers. These custom fetchers (e.g. Slack/Telegram media) wrap Node's built-in fetch(), which bundles its own undici 8.x internally. The handler interface changed between undici 7→8, causing the version mismatch error.
  • Fix: strip the dispatcher property from init before forwarding to custom fetchImpl callers. The SSRF DNS-pinning validation has already been performed before the custom fetcher is invoked, so security guarantees are preserved.

Test plan

  • Existing fetch-guard.ssrf.test.ts tests pass (no behavior change for runtime-fetch path)
  • Slack file attachment download works on Node 22+ with undici 8.x
  • Verify SSRF protection still blocks private IPs when custom fetchImpl is used

Fixes #62218

🤖 Generated with Claude Code

Changed files

  • extensions/slack/src/monitor/media.ts (modified, +6/-2)

PR #65369: browser: use raw node:http for loopback CDP reachability checks

Description (problem / solution / changelog)

Summary

  • The global undici EnvHttpProxyAgent dispatcher silently interferes with fetch() to localhost, causing isChromeReachable and isChromeCdpReady to fail even when Chrome CDP is listening on 127.0.0.1
  • Chrome starts successfully but gets killed after the 15s timeout because the SSRF-guarded fetch never connects
  • Adds lightweight loopback-only probes using raw node:http for isChromeReachable and isChromeCdpReady when the CDP URL targets 127.0.0.1, localhost, or ::1
  • Non-loopback URLs continue through the existing fetchWithSsrFGuard path unchanged

Related issues

  • Fixes #65379
  • Related to #62181 — globalThis.fetch (undici) does not honor HTTP_PROXY/HTTPS_PROXY env vars
  • Related to #32947 — web_fetch always fails (fetch failed) even for https://example.com, while curl works
  • Related to #5361 — Persistent Browser Control Timeout on Windows (same symptom, different platform)

Context

Discovered on a Linux gateway (Ubuntu, Node 24, Chrome 146) running as a systemd service. Chrome launches headed on DISPLAY=:10, DevTools listens on port 18800 (confirmed via curl and a background probe script), but the gateway's internal polling via fetchCdpCheckedfetchWithSsrFGuard consistently fails to connect within the 15-second window. Plain node:http.get to the same URL succeeds in <50ms.

Test plan

  • pnpm build passes
  • pnpm test extensions/browser — existing browser tests still pass
  • Manual: gateway detects Chrome CDP as reachable after launch on a Linux host with EnvHttpProxyAgent active

Changed files

  • extensions/browser/src/browser/chrome.ts (modified, +121/-2)

Code Example

const { EnvHttpProxyAgent, setGlobalDispatcher } = require('undici');
if (process.env.HTTPS_PROXY || process.env.HTTP_PROXY) {
  setGlobalDispatcher(new EnvHttpProxyAgent());
}
RAW_BUFFERClick to expand / collapse

Bug Report

Version

  • OpenClaw: 2026.4.5
  • Node: v22 (inside OpenShell sandbox)
  • undici: bundled with Node

Description

globalThis.fetch (powered by undici) does not route through HTTP_PROXY/HTTPS_PROXY by default. This means any code path that uses globalThis.fetch or undici's fetch() directly bypasses the proxy entirely.

In proxy-only environments (like OpenShell sandboxes where all traffic must go through an HTTP CONNECT proxy at 10.200.0.1:3128), this causes LLM provider requests to fail silently or with connection errors — the requests attempt direct connections that the network namespace blocks.

Affected Code Paths

  • OpenAI SDK v6+ uses globalThis.fetch internally
  • Any undici-based HTTP calls in OpenClaw or its plugins
  • This is separate from the SSRF fetch-guard DNS pinning issue (#59005) — even with that fix, undici's default Agent dispatcher has no proxy awareness

Workaround

At Node.js startup (via NODE_OPTIONS=--require), manually set the global dispatcher:

const { EnvHttpProxyAgent, setGlobalDispatcher } = require('undici');
if (process.env.HTTPS_PROXY || process.env.HTTP_PROXY) {
  setGlobalDispatcher(new EnvHttpProxyAgent());
}

This makes all globalThis.fetch calls honor proxy env vars. We've been running this in production across 4 OpenShell sandboxes since 2026.4.5.

Expected Behavior

When HTTP_PROXY/HTTPS_PROXY are set, OpenClaw should configure undici's global dispatcher to use EnvHttpProxyAgent so that all fetch-based requests route through the proxy — matching the behavior of Node's http/https modules.

Environment

  • OpenShell sandbox with HTTP CONNECT proxy (no direct internet, no DNS)
  • HTTP_PROXY=http://10.200.0.1:3128 and HTTPS_PROXY=http://10.200.0.1:3128 exported

Related Issues

  • #59005 / PR #59007 — DNS pinning before proxy check (same proxy environment, different layer)
  • #57405 — Slack Socket Mode ws library also doesn't honor HTTPS_PROXY
  • #52162 — memory_search remote embeddings fail behind proxy

extent analysis

TL;DR

Set the global dispatcher to EnvHttpProxyAgent at Node.js startup to make globalThis.fetch honor proxy environment variables.

Guidance

  • To fix the issue, set the global dispatcher using the provided workaround code at Node.js startup via NODE_OPTIONS=--require.
  • Verify that HTTP_PROXY and HTTPS_PROXY environment variables are set correctly before starting Node.js.
  • Ensure that the undici version bundled with Node is compatible with the EnvHttpProxyAgent class.
  • Test the fix by making a fetch request to a URL that requires proxy routing and verify that the request is successful.

Example

const { EnvHttpProxyAgent, setGlobalDispatcher } = require('undici');
if (process.env.HTTPS_PROXY || process.env.HTTP_PROXY) {
  setGlobalDispatcher(new EnvHttpProxyAgent());
}

Notes

This fix assumes that the undici version is compatible with the EnvHttpProxyAgent class. If issues persist, verify the undici version and check for any known compatibility issues.

Recommendation

Apply the workaround by setting the global dispatcher to EnvHttpProxyAgent at Node.js startup, as this has been successfully tested in production environments.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING