openclaw - ✅(Solved) Fix [Bug] Discord plugin: REST gateway metadata fetch bypasses account proxy, only WebSocket uses it [1 pull requests, 1 comments, 2 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#80227Fetched 2026-05-11 03:17:20
View on GitHub
Comments
1
Participants
2
Timeline
7
Reactions
2
Timeline (top)
cross-referenced ×2mentioned ×2subscribed ×2commented ×1

Error Message

Connect Timeout Error (attempted address: discord.com:443, timeout: 10000ms))

Root Cause

In provider-CuOh6z_b.js, when proxy is validated:

let fetchImpl = createDiscordGatewayMetadataFetch(debugProxySettings.enabled);
let wsAgent = new Agent({ lookup: discordDnsLookup$1 });

if (proxy) try {
  validateDiscordProxyUrl(proxy);
  wsAgent = new HttpsProxyAgent(proxy);  // ✅ WebSocket uses proxy
  // ❌ fetchImpl is NOT updated - still uses direct fetch
  params.runtime.log?.("discord: gateway proxy enabled");
}
ComponentProxy?
wsAgent (WebSocket)✅ Yes
fetchImpl (Gateway metadata REST)❌ No - uses fetchWithSsrFGuard directly

fetchDiscordGatewayMetadataDirect calls OpenClaw internal fetchWithSsrFGuard which does not read Discord plugin proxy config. In mainland China, direct discord.com connection is blocked by GFW → 10s timeout.

Fix Action

Fix / Workaround

Verified Workaround

Using global-agent monkey-patches all Node.js HTTP requests:

PR fix notes

PR #80252: fix(discord): proxy gateway metadata fetch

Description (problem / solution / changelog)

Summary

  • Problem: Discord gateway metadata lookup ignored the configured account/channel proxy while the WebSocket path used it.
  • Why it matters: users behind networks that block direct Discord REST traffic can configure a proxy, see discord: gateway proxy enabled, but still time out fetching /api/v10/gateway/bot.
  • What changed: when the Discord proxy validates successfully, gateway metadata fetches now use fetchWithSsrFGuard in guarded explicit-proxy mode while preserving the discord.com hostname allowlist.
  • What did NOT change (scope boundary): invalid or non-loopback proxies still fall back to the direct guarded metadata fetch path; regular Discord REST and WebSocket proxy setup are unchanged.

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 #80227
  • This PR fixes a bug or regression

Real behavior proof (required for external PRs)

  • Behavior or issue addressed: Discord gateway metadata fetch now follows the configured Discord proxy instead of bypassing it.
  • Real environment tested: Not live-tested against Discord/proxy; local verification was blocked by dependency resolution in this checkout.
  • Exact steps or command run after this patch: pnpm test extensions/discord/src/monitor/provider.proxy.test.ts extensions/discord/src/monitor/provider.rest-proxy.test.ts src/infra/net/fetch-guard.ssrf.test.ts
  • Evidence after fix: command failed before executing tests because @openclaw/fs-safe/config could not be imported from src/infra/fs-safe-defaults.ts.
  • Observed result after fix: source-level regression coverage was updated to assert guarded explicit-proxy parameters for /gateway/bot.
  • What was not tested: live Mainland China/proxy Discord startup and local test pass due dependency install/import blocker.
  • Before evidence (optional but encouraged): existing test asserted the metadata lookup stayed on guarded direct fetch with proxy configured.

Root Cause (if applicable)

  • Root cause: createDiscordGatewayPlugin validated the Discord proxy and applied it only to the gateway WebSocket agent; fetchImpl for /api/v10/gateway/bot remained the default direct SSRF-guarded fetch.
  • Missing detection / guardrail: the proxy regression test locked in direct metadata fetch behavior instead of verifying the configured proxy path.
  • Contributing context (if known): this path carries bot authorization, so the fix keeps SSRF guard and the Discord hostname allowlist instead of using a raw proxy fetch.

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: extensions/discord/src/monitor/provider.proxy.test.ts
  • Scenario the test should lock in: with discordConfig.proxy set to a validated loopback proxy, /api/v10/gateway/bot is fetched through trusted_explicit_proxy with an explicit-proxy dispatcher policy and discord.com allowlist.
  • Why this is the smallest reliable guardrail: it exercises the gateway plugin construction path that chooses both the WebSocket agent and metadata fetch implementation.
  • Existing test that already covers this (if any): the previous direct-fetch assertion was replaced.

User-visible / Behavior Changes

Discord users with a validated loopback channels.discord.proxy / account proxy now route gateway metadata REST startup through that proxy, matching gateway WebSocket behavior.

Diagram (if applicable)

Before:
Discord proxy config -> gateway WebSocket proxy
Discord proxy config -> /gateway/bot direct fetch -> timeout on blocked networks

After:
Discord proxy config -> gateway WebSocket proxy
Discord proxy config -> guarded explicit-proxy /gateway/bot fetch -> Discord metadata

Security Impact (required)

  • New permissions/capabilities? No
  • Secrets/tokens handling changed? Yes
  • New/changed network calls? Yes
  • Command/tool execution surface changed? No
  • Data access scope changed? No
  • If any Yes, explain risk + mitigation: the bot-token-bearing gateway metadata request may now traverse the already-configured Discord proxy. The proxy URL is still validated as loopback-only, the target remains allowlisted to discord.com, and the request remains inside fetchWithSsrFGuard using guarded explicit-proxy mode.

Repro + Verification

Environment

  • OS: macOS local checkout
  • Runtime/container: Node/pnpm workspace
  • Model/provider: N/A
  • Integration/channel (if any): Discord plugin
  • Relevant config (redacted): discordConfig.proxy = http://127.0.0.1:8080 in unit coverage

Steps

  1. Configure Discord proxy.
  2. Start/register the Discord gateway plugin.
  3. Observe /api/v10/gateway/bot fetch path.

Expected

  • Gateway metadata REST lookup uses the configured guarded explicit proxy.

Actual

  • Before this patch, only WebSocket used the proxy; metadata fetch remained direct.

Evidence

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

Local test command attempted:

pnpm test extensions/discord/src/monitor/provider.proxy.test.ts extensions/discord/src/monitor/provider.rest-proxy.test.ts src/infra/net/fetch-guard.ssrf.test.ts

Blocked locally before tests ran:

Error: Cannot find package '@openclaw/fs-safe/config' imported from src/infra/fs-safe-defaults.ts

I also ran pnpm install once as requested by the repo instructions. It did not complete cleanly because the configured registry mirror returned 404 for @opentelemetry/[email protected], after a prepack substep also reported unrelated @types/web-bluetooth DOM type errors.

Human Verification (required)

What I personally verified (not just CI), and how:

  • Verified scenarios: source-level path from discordConfig.proxy through createDiscordGatewayPlugin now swaps metadata fetch implementation to guarded explicit-proxy mode.
  • Edge cases checked: invalid proxy branch still logs an error and resets metadata fetch to direct guarded fetch.
  • What you did not verify: live Discord connection through a real proxy; local Vitest pass due dependency/import blocker above.

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

Risks and Mitigations

  • Risk: routing a bot-token-bearing metadata request through proxy changes token egress.
    • Mitigation: only already-configured, validated loopback proxies are used; target hostname remains allowlisted and SSRF guard stays in the path.

Changed files

  • extensions/discord/src/monitor/gateway-metadata.ts (modified, +14/-0)
  • extensions/discord/src/monitor/gateway-plugin.ts (modified, +22/-0)
  • extensions/discord/src/monitor/provider.proxy.test.ts (modified, +18/-4)

Code Example

[fetch-timeout] fetch timeout after 10000ms operation=fetchWithTimeout url=https://discord.com/api/v10/users/@me

---

[discord] rest proxy enabled
[discord] gateway proxy enabled
[discord] [default] Discord bot probe resolved @Claude代码妹妹
[discord] gateway metadata lookup failed transiently; using default gateway url
(Failed to get gateway information from Discord: fetch failed | fetch failed |
Connect Timeout Error (attempted address: discord.com:443, timeout: 10000ms))

---

let fetchImpl = createDiscordGatewayMetadataFetch(debugProxySettings.enabled);
let wsAgent = new Agent({ lookup: discordDnsLookup$1 });

if (proxy) try {
  validateDiscordProxyUrl(proxy);
  wsAgent = new HttpsProxyAgent(proxy);  // ✅ WebSocket uses proxy
  // ❌ fetchImpl is NOT updated - still uses direct fetch
  params.runtime.log?.("discord: gateway proxy enabled");
}

---

export HTTP_PROXY='http://127.0.0.1:7890'
export HTTPS_PROXY='http://127.0.0.1:7890'
export GLOBAL_AGENT_HTTP_PROXY='http://127.0.0.1:7890'
export GLOBAL_AGENT_HTTPS_PROXY='http://127.0.0.1:7890'

---

if (proxy) try {
  validateDiscordProxyUrl(proxy);
  wsAgent = new HttpsProxyAgent(proxy);
  fetchImpl = createProxyFetchImpl(proxy);  // ← add this
  params.runtime.log?.("discord: gateway proxy enabled");
}
RAW_BUFFERClick to expand / collapse

Environment

  • OS: macOS 15.3
  • OpenClaw: v2026.5.6
  • Discord Plugin: v2026.5.7
  • Proxy: ClashX Pro HTTP/SOCKS5 mixed proxy @ 127.0.0.1:7890
  • Network: Mainland China (GFW blocks Discord)

Problem

Discord bot stays offline. Two timeout errors:

1. REST API timeout:

[fetch-timeout] fetch timeout after 10000ms operation=fetchWithTimeout url=https://discord.com/api/v10/users/@me

2. Gateway metadata fetch fails:

[discord] rest proxy enabled
[discord] gateway proxy enabled
[discord] [default] Discord bot probe resolved @Claude代码妹妹
[discord] gateway metadata lookup failed transiently; using default gateway url
(Failed to get gateway information from Discord: fetch failed | fetch failed |
Connect Timeout Error (attempted address: discord.com:443, timeout: 10000ms))

Root Cause

In provider-CuOh6z_b.js, when proxy is validated:

let fetchImpl = createDiscordGatewayMetadataFetch(debugProxySettings.enabled);
let wsAgent = new Agent({ lookup: discordDnsLookup$1 });

if (proxy) try {
  validateDiscordProxyUrl(proxy);
  wsAgent = new HttpsProxyAgent(proxy);  // ✅ WebSocket uses proxy
  // ❌ fetchImpl is NOT updated - still uses direct fetch
  params.runtime.log?.("discord: gateway proxy enabled");
}
ComponentProxy?
wsAgent (WebSocket)✅ Yes
fetchImpl (Gateway metadata REST)❌ No - uses fetchWithSsrFGuard directly

fetchDiscordGatewayMetadataDirect calls OpenClaw internal fetchWithSsrFGuard which does not read Discord plugin proxy config. In mainland China, direct discord.com connection is blocked by GFW → 10s timeout.

Verified Workaround

Using global-agent monkey-patches all Node.js HTTP requests:

export HTTP_PROXY='http://127.0.0.1:7890'
export HTTPS_PROXY='http://127.0.0.1:7890'
export GLOBAL_AGENT_HTTP_PROXY='http://127.0.0.1:7890'
export GLOBAL_AGENT_HTTPS_PROXY='http://127.0.0.1:7890'

This works because it forces all requests through proxy, bypassing the plugin's incomplete proxy configuration.

Suggested Fix

When proxy is validated, also update fetchImpl to use the proxy:

if (proxy) try {
  validateDiscordProxyUrl(proxy);
  wsAgent = new HttpsProxyAgent(proxy);
  fetchImpl = createProxyFetchImpl(proxy);  // ← add this
  params.runtime.log?.("discord: gateway proxy enabled");
}

Or make fetchDiscordGatewayMetadataDirect respect Discord plugin proxy settings.

Additional Suggestions

  1. Docs: Clarify proxy setup for mainland China users
  2. Validation: openclaw config validate should verify Discord proxy connectivity
  3. Consistency: Ensure all outbound requests (REST + WebSocket) use the same proxy

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

openclaw - ✅(Solved) Fix [Bug] Discord plugin: REST gateway metadata fetch bypasses account proxy, only WebSocket uses it [1 pull requests, 1 comments, 2 participants]