Skip to content

fix(net): bound guarded fetch dispatcher cleanup#78439

Merged
obviyus merged 3 commits into
mainfrom
ayaan/web-fetch-stuck-regression
May 6, 2026
Merged

fix(net): bound guarded fetch dispatcher cleanup#78439
obviyus merged 3 commits into
mainfrom
ayaan/web-fetch-stuck-regression

Conversation

@obviyus

@obviyus obviyus commented May 6, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Bound guarded-fetch dispatcher cleanup so timeout/error paths cannot hang behind a stalled undici close.
  • Add regression coverage for a timed-out fetch whose dispatcher close never resolves.

Real behavior proof

  • Behavior or issue addressed: A timed-out guarded web_fetch must finish with a tool error instead of leaving the Gateway/tool lane stuck behind dispatcher cleanup.
  • Real environment tested: Local OpenClaw candidate gateway from this PR head (9bb72ae) on macOS, profile web-fetch-proof, port 19089, token auth, real Gateway HTTP POST /tools/invoke surface.
  • Exact steps or command run after this patch: Started pnpm openclaw --profile web-fetch-proof gateway run --port 19089 --auth token --token <redacted> --allow-unconfigured --dev --compact, then called POST /tools/invoke for web_fetch against https://1.1.1.1:81/; while that request was pending and again after it completed, checked /health and called web_fetch against https://example.com/.
  • Evidence after fix: Redacted runtime log excerpt: 16:56:39 [fetch-timeout] fetch timeout after 30000ms (elapsed 30002ms) operation=fetchWithSsrFGuard url=https://1.1.1.1:81/; 16:56:39 [tools-invoke] tool execution failed: TimeoutError: request timed out. Live output during/after: /health returned {"ok":true,"status":"live"}; web_fetch for https://example.com/ returned {"ok":true,..."status":200...}.
  • Observed result after fix: The timed-out fetch returned a tool error after about 30s, the gateway stayed live during the pending request, and a later web_fetch still succeeded with HTTP 200.
  • What was not tested: Full Telegram group roundtrip was not rerun; this proof exercises the shared Gateway tools.invoke and web_fetch timeout path directly.

Verification

  • pnpm test src/infra/net/fetch-guard.ssrf.test.ts -- --reporter=verbose
  • OPENCLAW_LOCAL_CHECK_MODE=throttled OPENCLAW_TESTBOX=0 pnpm check:changed
  • OPENCLAW_LOCAL_CHECK_MODE=throttled OPENCLAW_TESTBOX=0 pnpm test:changed
  • pnpm exec oxfmt --check --threads=1 src/infra/net/ssrf.ts src/infra/net/fetch-guard.ssrf.test.ts
  • git diff --check

@openclaw-barnacle openclaw-barnacle Bot added size: S maintainer Maintainer-authored PR labels May 6, 2026
@obviyus obviyus self-assigned this May 6, 2026
@clawsweeper

clawsweeper Bot commented May 6, 2026

Copy link
Copy Markdown
Contributor

ClawSweeper status: review started.

I am starting a fresh review of this pull request: fix(net): bound guarded fetch dispatcher cleanup This is item 1/1 in the current shard. Shard 0/1.

This placeholder means the worker is alive and reading the current context. I will edit this same comment with the actual review when the claws are done clicking.

Crustacean status: shell secured, claws on keyboard, evidence pebbles being sorted.

@obviyus
obviyus force-pushed the ayaan/web-fetch-stuck-regression branch from 9bb72ae to 5acded5 Compare May 6, 2026 11:38
@obviyus
obviyus merged commit 855a7c7 into main May 6, 2026
95 checks passed
@obviyus
obviyus deleted the ayaan/web-fetch-stuck-regression branch May 6, 2026 11:41
@obviyus

obviyus commented May 6, 2026

Copy link
Copy Markdown
Contributor Author

Landed on main.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

maintainer Maintainer-authored PR size: S

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant