Description
A sandbox onboarded with the Discord channel comes up degraded: the bot sends via the Discord REST API but never establishes the Discord Gateway WebSocket (wss://gateway.discord.gg), so it receives zero MESSAGE_CREATE / mention events. The bot looks alive from outside (REST polling succeeds, status is Ready) but the entire inbound half of Discord is silently black-holed. This is the same symptom as #3894.
Root cause
#3935 originally fixed #3894 by setting channels.discord.accounts.default.proxy in the config generator, with the rationale (quoted from its own e2e proof) that OpenClaw's Discord gateway client ignores proxy env vars and only honors the per-account proxy setting.
#4005 then removed that per-account proxy, on the premise that "OpenClaw 2026.5.18's top-level managed proxy support covers the Discord Gateway case directly". #4277 ported config generation to scripts/generate-openclaw-config.mts and kept the managed-proxy-only approach, narrowing the per-account proxy assignment to Telegram:
if (ch === "telegram") {
account.proxy = proxyUrl;
}
The managed proxy block (config.proxy, loopbackMode: "gateway-only") is applied by injecting HTTP(S)_PROXY into the environment. But OpenClaw's Discord gateway client does not consume the proxy env vars. In extensions/discord/src/monitor/gateway-plugin.ts, createWebSocket opens the socket with the classic ws transport and an explicit agent:
const socket = new WebSocketCtor(url, {
handshakeTimeout: ...,
...(params.wsAgent ? { agent: params.wsAgent } : {}),
});
and that wsAgent is a proxy CONNECT agent only when discordConfig.proxy (the per-account value) is set; otherwise it is a direct-DNS https.Agent:
let wsAgent = new HttpsAgent({ lookup: discordDnsLookup });
if (proxy) { wsAgent = createNodeProxyAgent({ mode: "explicit", proxyUrl: proxy, protocol: "https" }); }
With no per-account proxy, the gateway client resolves gateway.discord.gg via direct DNS, which has no resolver to answer it in a proxy-only sandbox (EAI_AGAIN), so the socket never opens.
On #4005's validation
#4005's e2e (test/e2e/lib/discord-gateway-proof.sh) proves the sandbox network path by driving a fake gateway with a standalone Node/Python client that reads HTTP_PROXY and tunnels through the proxy. That confirms the relay works, but it does not exercise OpenClaw's real gateway transport, which (verified identical at OpenClaw 2026.5.18, 2026.5.27, and 2026.6.1) uses the classic ws agent and only tunnels when the per-account proxy is set. So the managed proxy never covered the real gateway client, and removing the per-account proxy re-regressed #3894.
A version bump does not help: the relevant gateway transport is unchanged across 2026.5.18 -> 2026.6.1.
Expected
The generated openclaw.json sets channels.discord.accounts.default.proxy to the sandbox proxy URL (as #3935 did), so the gateway client tunnels via the proxy instead of attempting direct DNS.
Fix
Restore Discord to the per-account proxy assignment in generate-openclaw-config.mts (mirroring Telegram), and update the generator tests that currently assert the Discord account proxy is absent.
Description
A sandbox onboarded with the Discord channel comes up degraded: the bot sends via the Discord REST API but never establishes the Discord Gateway WebSocket (
wss://gateway.discord.gg), so it receives zeroMESSAGE_CREATE/ mention events. The bot looks alive from outside (REST polling succeeds, status is Ready) but the entire inbound half of Discord is silently black-holed. This is the same symptom as #3894.Root cause
#3935 originally fixed #3894 by setting
channels.discord.accounts.default.proxyin the config generator, with the rationale (quoted from its own e2e proof) that OpenClaw's Discord gateway client ignores proxy env vars and only honors the per-account proxy setting.#4005 then removed that per-account proxy, on the premise that "OpenClaw 2026.5.18's top-level managed proxy support covers the Discord Gateway case directly". #4277 ported config generation to
scripts/generate-openclaw-config.mtsand kept the managed-proxy-only approach, narrowing the per-account proxy assignment to Telegram:The managed proxy block (
config.proxy,loopbackMode: "gateway-only") is applied by injectingHTTP(S)_PROXYinto the environment. But OpenClaw's Discord gateway client does not consume the proxy env vars. Inextensions/discord/src/monitor/gateway-plugin.ts,createWebSocketopens the socket with the classicwstransport and an explicit agent:and that
wsAgentis a proxy CONNECT agent only whendiscordConfig.proxy(the per-account value) is set; otherwise it is a direct-DNShttps.Agent:With no per-account proxy, the gateway client resolves
gateway.discord.ggvia direct DNS, which has no resolver to answer it in a proxy-only sandbox (EAI_AGAIN), so the socket never opens.On #4005's validation
#4005's e2e (
test/e2e/lib/discord-gateway-proof.sh) proves the sandbox network path by driving a fake gateway with a standalone Node/Python client that readsHTTP_PROXYand tunnels through the proxy. That confirms the relay works, but it does not exercise OpenClaw's real gateway transport, which (verified identical at OpenClaw 2026.5.18, 2026.5.27, and 2026.6.1) uses the classicwsagent and only tunnels when the per-account proxy is set. So the managed proxy never covered the real gateway client, and removing the per-account proxy re-regressed #3894.A version bump does not help: the relevant gateway transport is unchanged across 2026.5.18 -> 2026.6.1.
Expected
The generated
openclaw.jsonsetschannels.discord.accounts.default.proxyto the sandbox proxy URL (as #3935 did), so the gateway client tunnels via the proxy instead of attempting direct DNS.Fix
Restore Discord to the per-account proxy assignment in
generate-openclaw-config.mts(mirroring Telegram), and update the generator tests that currently assert the Discord account proxy is absent.