openclaw - ✅(Solved) Fix Regression: external channel plugin fetch() fails with TypeError: fetch failed in 2026.5.4 [2 pull requests, 2 comments, 3 participants]

Official PRs (…)
ON THIS PAGE

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#78007Fetched 2026-05-06 06:17:57
View on GitHub
Comments
2
Participants
3
Timeline
13
Reactions
2
Author
Assignees
Timeline (top)
cross-referenced ×3mentioned ×3subscribed ×3commented ×2

All fetch() calls inside external channel plugins fail with TypeError: fetch failed when running inside the OpenClaw 2026.5.4 gateway process. The same fetch calls succeed outside the gateway (curl, standalone node, CLI subcommands).

Error Message

CLI login command (spawns gateway subcommand)

$ openclaw channels login --channel openclaw-weixin Failed to start login: TypeError: fetch failed

Gateway channel worker log (repeats every restart cycle)

[channel] notifyStart failed during startup (ignored): TypeError: fetch failed [channel] waitForWeixinRuntime() failed: Error: Weixin runtime initialization timeout

Root Cause

Workaround

None found. Manually obtaining the QR code via curl and writing credentials to ~/.openclaw/openclaw-weixin/accounts/ allows the channel to appear as ON / OK in openclaw status, but the channel worker still cannot poll for messages because all fetch calls fail.

Fix Action

Workaround

None found. Manually obtaining the QR code via curl and writing credentials to ~/.openclaw/openclaw-weixin/accounts/ allows the channel to appear as ON / OK in openclaw status, but the channel worker still cannot poll for messages because all fetch calls fail.

PR fix notes

PR #78040: Ignore unsupported proxy schemes for env dispatcher

Description (problem / solution / changelog)

Fixes #78007.

Summary

  • restrict EnvHttpProxyAgent options to HTTP(S) proxy URLs
  • ignore unsupported schemes such as socks5: for the gateway/global Undici HTTP proxy dispatcher
  • preserve HTTP ALL_PROXY fallback behavior

Verification

  • PATH="/tmp/openclaw-pnpm-shim:$PATH" node scripts/test-projects.mjs src/infra/net/proxy-env.test.ts src/infra/net/undici-global-dispatcher.test.ts --maxWorkers=1
  • git diff --check
  • PATH="/tmp/openclaw-pnpm-shim:$PATH" node scripts/check-changed.mjs

Changed files

  • src/infra/net/proxy-env.test.ts (modified, +11/-6)
  • src/infra/net/proxy-env.ts (modified, +20/-3)
  • src/infra/net/undici-global-dispatcher.test.ts (modified, +5/-5)

PR #78143: fix(runtime): avoid no-proxy undici fetch side effects

Description (problem / solution / changelog)

Summary

  • Problem: external channel plugin startup could import OpenClaw's packaged Undici proxy helpers on a clean no-proxy path, changing process-level fetch behavior before the plugin called globalThis.fetch.
  • Why it matters: openclaw channels login --channel openclaw-weixin failed for @tencent-weixin/[email protected] with TypeError: fetch failed even though the same request worked in plain Node fetch.
  • What changed: lazy-load Undici dispatcher/proxy dependencies only when OpenClaw actually creates a proxy fetch or proxy dispatcher, while keeping the guarded-fetch timeout bridge and proxy reset behavior intact.
  • What did NOT change (scope boundary): no plugin code is changed, no proxy env contract is removed, and no configured proxy path is intentionally bypassed.

Change Type (select all)

  • Bug fix
  • Feature
  • Refactor required for the fix
  • Docs
  • Security hardening
  • Chore/infra

Scope (select all touched areas)

  • Gateway / orchestration
  • Skills / tool execution
  • Auth / tokens
  • Memory / storage
  • Integrations
  • API / contracts
  • UI / DX
  • CI/CD / infra

Linked Issue/PR

  • Closes #78007
  • Related #78040
  • This PR fixes a bug or regression

Real behavior proof (required for external PRs)

  • Behavior or issue addressed: Tencent Weixin channel login failed before QR startup because the plugin's plain fetch request was rejected after OpenClaw loaded packaged Undici helpers.
  • Real environment tested: source checkout on macOS with isolated HOME, isolated OPENCLAW_STATE_DIR, and @tencent-weixin/[email protected] installed through openclaw plugins install.
  • Exact steps or command run after this patch:
    1. pnpm openclaw plugins install @tencent-weixin/[email protected] --pin
    2. pnpm openclaw channels login --channel openclaw-weixin --verbose
  • Evidence after fix:
[plugins] loading openclaw-weixin from /private/tmp/openclaw-78007.Ez0VWR/.openclaw/npm/node_modules/@tencent-weixin/openclaw-weixin/dist/index.js
[plugins] loaded 1 plugin(s) (1 attempted) in 1516.5ms
用手机微信扫描以下二维码,以继续连接:
若二维码未能显示或无法使用,你可以访问以下链接以继续:
https://liteapp.weixin.qq.com/q/7GiQu1?qrcode=3e04d58f044ba6b007fc02cca258bf48&bot_type=3
  • Observed result after fix: the login flow reaches QR startup instead of failing at TypeError: fetch failed.
  • What was not tested: scanning the QR code and completing the Weixin account-linking flow.
  • Before evidence:
Failed to start login: TypeError: fetch failed
Channel login failed: Error: Failed to start login: TypeError: fetch failed

Trace before fix showed the underlying cause:

UND_ERR_INVALID_ARG: invalid content-length header

Root Cause (if applicable)

  • Root cause: src/infra/net/proxy-fetch.ts imported Undici at module load time. That module is exported through plugin runtime helper surfaces, so loading external plugin code could initialize Undici's package dispatcher state even when no proxy was configured. With the current Undici dependency, that changed Node global fetch behavior and caused plugin requests with explicit Content-Length to fail.
  • Missing detection / guardrail: there was no regression test proving clean no-proxy startup does not initialize Undici global dispatcher state.
  • Contributing context (if known): the affected plugin sends an explicit Content-Length header; plain Node fetch accepts the request, but OpenClaw's import side effect made the same request fail.

Regression Test Plan (if applicable)

  • Coverage level that should have caught this:
    • Unit test
    • Seam / integration test
    • End-to-end test
    • Existing coverage already sufficient
  • Target test or file:
    • src/infra/net/undici-global-dispatcher.test.ts
    • src/infra/net/proxy-fetch.test.ts
    • src/infra/net/fetch-guard.ssrf.test.ts
  • Scenario the test should lock in: no-proxy timeout setup and proxy helper import must not initialize Undici global dispatcher state; proxy fetch and env proxy paths must still lazy-load and use Undici when needed.
  • Why this is the smallest reliable guardrail: the regression was an import-time side effect, so a subprocess assertion against the global dispatcher symbol catches the exact failure class without requiring live third-party auth.
  • Existing test that already covers this (if any): none before this PR.
  • If no new test is added, why not: N/A.

User-visible / Behavior Changes

External channel plugins that use plain fetch() no longer inherit OpenClaw's packaged Undici dispatcher behavior on clean no-proxy startup. This fixes the Weixin QR login regression in #78007.

Diagram (if applicable)

Before:
plugin load -> SDK/runtime helper import -> proxy-fetch imports Undici -> plugin fetch fails

After:
plugin load -> SDK/runtime helper import -> no Undici import unless proxy fetch is created -> plugin fetch reaches QR login

Security Impact (required)

  • New permissions/capabilities? No
  • Secrets/tokens handling changed? No
  • New/changed network calls? No
  • Command/tool execution surface changed? No
  • Data access scope changed? No
  • If any Yes, explain risk + mitigation: N/A

Repro + Verification

Environment

  • OS: macOS local checkout; Blacksmith Testbox for remote validation
  • Runtime/container: source checkout, Node 24, pnpm 10
  • Model/provider: N/A
  • Integration/channel: @tencent-weixin/[email protected]
  • Relevant config (redacted): isolated state dir with only the installed plugin enabled

Steps

  1. Install @tencent-weixin/[email protected] into an isolated state dir.
  2. Run pnpm openclaw channels login --channel openclaw-weixin --verbose.
  3. Confirm the command reaches QR login output instead of failing with TypeError: fetch failed.

Expected

  • The Weixin login request reaches QR login startup.

Actual

  • After this patch, the command reaches QR login startup.

Evidence

  • Failing test/log before + passing after
  • Trace/log snippets
  • Screenshot/recording
  • Perf numbers (if relevant)

Human Verification (required)

What I personally verified:

  • pnpm test src/infra/net/proxy-fetch.test.ts src/infra/net/undici-global-dispatcher.test.ts src/infra/net/fetch-guard.ssrf.test.ts
  • Same targeted test command passed in Blacksmith Testbox.
  • pnpm exec oxfmt --check --threads=1 CHANGELOG.md src/infra/net/proxy-fetch.ts src/infra/net/proxy-fetch.test.ts src/infra/net/undici-runtime.ts src/infra/net/undici-global-dispatcher.ts src/infra/net/undici-global-dispatcher.test.ts src/infra/net/fetch-guard.ssrf.test.ts
  • git diff --check
  • Real isolated openclaw channels login --channel openclaw-weixin --verbose reached QR login output.

Edge cases checked:

  • No-proxy timeout setup does not initialize Undici global dispatcher state.
  • Env proxy setup still installs EnvHttpProxyAgent.
  • Proxy fetch still creates ProxyAgent lazily.
  • FormData normalization still strips stale content-length/content-type in proxy fetch paths.
  • Clearing a proxy dispatcher installed by OpenClaw still restores a direct dispatcher.

What I did not verify:

  • Full Weixin account-linking after QR scan.
  • Full repo test suite.

Note: pnpm check:changed was run in Blacksmith Testbox after rebase and failed in tsgo:core:test on src/agents/model-fallback.test.ts, which this PR does not touch:

src/agents/model-fallback.test.ts(1091,22): error TS2339: Property 'expectedReason' does not exist on type ...
src/agents/model-fallback.test.ts(1093,60): error TS2339: Property 'expectedReason' does not exist on type ...

Review Conversations

  • I replied to or resolved every bot review conversation I addressed in this PR.
  • I left unresolved only the conversations that still need reviewer or maintainer judgment.

Compatibility / Migration

  • Backward compatible? Yes
  • Config/env changes? No
  • Migration needed? No
  • If yes, exact upgrade steps: N/A

Risks and Mitigations

  • Risk: proxy paths could stop loading Undici too early.
    • Mitigation: proxy fetch and env proxy dispatcher tests assert lazy creation still loads and uses the expected Undici agents.
  • Risk: direct guarded fetches could lose timeout propagation.
    • Mitigation: guarded fetch tests still assert the timeout bridge is inherited by direct guarded dispatchers.

Changed files

  • CHANGELOG.md (modified, +1/-0)
  • src/agents/pi-embedded-runner/run/attempt-http-runtime.ts (modified, +2/-2)
  • src/agents/pi-embedded-runner/run/attempt.spawn-workspace.test-support.ts (modified, +6/-0)
  • src/agents/pi-embedded-runner/run/attempt.spawn-workspace.timeout.test.ts (modified, +5/-5)
  • src/infra/net/fetch-guard.ssrf.test.ts (modified, +0/-3)
  • src/infra/net/fetch-guard.ts (modified, +46/-18)
  • src/infra/net/proxy-fetch.test.ts (modified, +12/-7)
  • src/infra/net/proxy-fetch.ts (modified, +27/-12)
  • src/infra/net/undici-global-dispatcher.test.ts (modified, +105/-25)
  • src/infra/net/undici-global-dispatcher.ts (modified, +86/-29)
  • src/infra/net/undici-runtime.ts (modified, +32/-0)
  • src/plugin-sdk/fetch-runtime.test.ts (added, +38/-0)
  • src/proxy-capture/env.ts (modified, +10/-1)

Code Example

# curl — works
$ curl -s -X POST "https://ilinkai.weixin.qq.com/ilink/bot/get_bot_qrcode?bot_type=3" \
  -H "Content-Type: application/json" -H "iLink-App-Id: bot" \
  -d '{"local_token_list":[]}'
{"qrcode":"...","qrcode_img_content":"...","ret":0}

# standalone node — works
$ node -e "fetch(\"https://ilinkai.weixin.qq.com/...\").then(r => console.log(\"OK\", r.status))"
fetch OK 200

---

# CLI login command (spawns gateway subcommand)
$ openclaw channels login --channel openclaw-weixin
Failed to start login: TypeError: fetch failed

# Gateway channel worker log (repeats every restart cycle)
[channel] notifyStart failed during startup (ignored): TypeError: fetch failed
[channel] waitForWeixinRuntime() failed: Error: Weixin runtime initialization timeout

---

[compat] Host OpenClaw 2026.5.4 >= 2026.3.22, OK.
[runtime] setWeixinRuntime called, runtime set successfully
RAW_BUFFERClick to expand / collapse

Bug Report

Environment

  • OpenClaw version: 2026.5.4 (stable channel)
  • OS: macOS 26.4.1 (arm64, Mac mini M4)
  • Node.js: v25.9.0
  • Plugin: @tencent-weixin/openclaw-weixin v2.4.1 (Weixin/WeChat personal account channel)

Description

All fetch() calls inside external channel plugins fail with TypeError: fetch failed when running inside the OpenClaw 2026.5.4 gateway process. The same fetch calls succeed outside the gateway (curl, standalone node, CLI subcommands).

Evidence

1. fetch works outside the gateway:

# curl — works
$ curl -s -X POST "https://ilinkai.weixin.qq.com/ilink/bot/get_bot_qrcode?bot_type=3" \
  -H "Content-Type: application/json" -H "iLink-App-Id: bot" \
  -d '{"local_token_list":[]}'
{"qrcode":"...","qrcode_img_content":"...","ret":0}

# standalone node — works
$ node -e "fetch(\"https://ilinkai.weixin.qq.com/...\").then(r => console.log(\"OK\", r.status))"
fetch OK 200

2. fetch fails inside the gateway process:

# CLI login command (spawns gateway subcommand)
$ openclaw channels login --channel openclaw-weixin
Failed to start login: TypeError: fetch failed

# Gateway channel worker log (repeats every restart cycle)
[channel] notifyStart failed during startup (ignored): TypeError: fetch failed
[channel] waitForWeixinRuntime() failed: Error: Weixin runtime initialization timeout

3. Plugin registers successfully — the issue is specifically with fetch():

[compat] Host OpenClaw 2026.5.4 >= 2026.3.22, OK.
[runtime] setWeixinRuntime called, runtime set successfully

Timeline / Repro

  1. Install OpenClaw 2026.5.4
  2. Install weixin plugin: npx -y @tencent-weixin/openclaw-weixin-cli install
  3. Plugin loads and registers fine (version check passes, runtime set)
  4. Any fetch() call from plugin code inside gateway process → TypeError: fetch failed
  5. Channel worker enters crash loop: fetch fails → runtime init timeout → restart → repeat

Hypothesis

OpenClaw 2026.5.4 appears to replace globalThis.fetch with a custom implementation (for request auditing, SSRF protection, or proxy routing based on the 2026.5.x changelog entries). This custom fetch breaks for external channel plugins that make outbound HTTPS requests to third-party APIs (e.g., https://ilinkai.weixin.qq.com).

The TypeError: fetch failed without any underlying cause info (no ECONNREFUSED, no ENOTFOUND, no AggregateError) suggests the custom fetch is rejecting the request before it reaches the network stack.

Workaround

None found. Manually obtaining the QR code via curl and writing credentials to ~/.openclaw/openclaw-weixin/accounts/ allows the channel to appear as ON / OK in openclaw status, but the channel worker still cannot poll for messages because all fetch calls fail.

Requested Fix

  • Ensure the gateway's custom fetch implementation (if any) transparently passes through external plugin HTTPS requests
  • Or document any new configuration needed for external channel plugins to make outbound network requests

extent analysis

TL;DR

The custom fetch implementation in OpenClaw 2026.5.4 may be causing issues with external channel plugins making outbound HTTPS requests, and a fix or workaround is needed to transparently pass through these requests.

Guidance

  • Verify that the custom fetch implementation is indeed the cause of the issue by checking the OpenClaw 2026.5.4 changelog and documentation for any changes related to request auditing, SSRF protection, or proxy routing.
  • Check if there are any configuration options or environment variables that can be set to allow external channel plugins to make outbound network requests.
  • Consider reaching out to the OpenClaw development team or community for further assistance, as this issue may be a known problem or require a specific fix.
  • In the meantime, the workaround of manually obtaining the QR code via curl and writing credentials to ~/.openclaw/openclaw-weixin/accounts/ can be used to get the channel to appear as ON / OK in openclaw status, but this does not fix the underlying issue.

Notes

The issue seems to be specific to the custom fetch implementation in OpenClaw 2026.5.4, and a fix or workaround will likely require changes to this implementation or additional configuration options.

Recommendation

Apply workaround: Manually obtain the QR code via curl and write credentials to ~/.openclaw/openclaw-weixin/accounts/ to get the channel to appear as ON / OK in openclaw status, while waiting for a fix or further assistance from the OpenClaw development team.

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