Skip to content

fix(discord): stop emitting a non-loopback per-account proxy (#5544)#5571

Open
latenighthackathon wants to merge 1 commit into
NVIDIA:mainfrom
latenighthackathon:fix-discord-drop-rejected-per-account-proxy
Open

fix(discord): stop emitting a non-loopback per-account proxy (#5544)#5571
latenighthackathon wants to merge 1 commit into
NVIDIA:mainfrom
latenighthackathon:fix-discord-drop-rejected-per-account-proxy

Conversation

@latenighthackathon

@latenighthackathon latenighthackathon commented Jun 21, 2026

Copy link
Copy Markdown
Contributor

Summary

The Discord channel config emits a per-account proxy (channels.discord.accounts.default.proxy = http://10.200.0.1:3128) that OpenClaw's Discord plugin rejects by design. extensions/discord/src/proxy-fetch.ts validateDiscordProxyUrl throws Proxy URL must target a loopback host for any non-loopback host, and that validator runs on both the REST and gateway transports. The rejected proxy is dropped, so the Discord gateway WebSocket cannot egress the deny-by-default network namespace and never reaches READY. This restores reliance on the top-level managed proxy for Discord, the mechanism that originally addressed #5075 / #3894.

Related Issue

Fixes #5544

Changes

  • Resolve discordProxyUrl back to undefined so the per-account proxy field is omitted from the rendered openclaw.json. Discord gateway and REST egress is carried by the top-level managed proxy (proxy.loopbackMode: "gateway-only"), which OpenClaw documents as the path for routing channel traffic through the operator proxy.
  • Telegram keeps its per-account proxy: its Bot API transport honors a non-loopback proxy and has no loopback validator. Discord uniquely validates loopback, so mirroring Telegram was the wrong shape for Discord.
  • Flip the generate-openclaw-config and discord template-resolver expectations back to asserting no per-account Discord proxy, and revert the messaging-providers M9b check to expect the managed proxy with no Discord account.proxy.
  • Effectively reverts fix(messaging): resolve the Discord per-account proxy so the gateway WebSocket connects #5248 (and its test(e2e): update Discord proxy expectation #5391 test follow-up).

Type of Change

  • Code change (feature, bug fix, or refactor)

Verification

  • PR description includes the DCO sign-off declaration and every commit appears as Verified in GitHub
  • Git hooks passed during commit and push, or npx prek run --from-ref main --to-ref HEAD passes
  • Targeted tests pass for changed behavior
  • Tests added or updated for new or changed behavior
  • No secrets, API keys, or credentials committed

Ran: npx vitest run test/discord-template-resolver-proxy.test.ts test/generate-openclaw-config.test.ts (130 passed), npm run build:cli, and biome check on the touched files (clean). The full-suite test-cli/test-plugin commit and push hooks were skipped because they trip on a pre-existing collection error in test/ssrf-parity.test.ts (0 tests collected) that also fails on a clean main checkout and is unrelated to this change. CI runs the full gate.


Signed-off-by: latenighthackathon latenighthackathon@users.noreply.github.com

…5544)

OpenClaw's Discord plugin validates channels.discord.accounts.default.proxy
and rejects any non-loopback host (extensions/discord/src/proxy-fetch.ts
validateDiscordProxyUrl: "Proxy URL must target a loopback host"), called
from both the REST and gateway-plugin transports. NemoClaw was rendering it
to the sandbox egress proxy http://10.200.0.1:3128, which the plugin rejects
and drops, so the Discord gateway WebSocket cannot egress the deny-by-default
namespace and never reaches READY.

Resolve discordProxyUrl back to undefined so the per-account proxy field is
omitted. Discord gateway/REST egress is carried by the top-level managed
proxy (proxy.loopbackMode "gateway-only"), the mechanism OpenClaw documents
for routing channel traffic through the operator proxy. Telegram keeps its
per-account proxy because its Bot API transport honors a non-loopback proxy
and has no loopback validator; Discord uniquely does.

Flip the generate-openclaw-config and template-resolver expectations back to
asserting no per-account Discord proxy, and revert the messaging-providers
M9b E2E check to expect the managed proxy with no Discord account.proxy.

Signed-off-by: latenighthackathon <latenighthackathon@users.noreply.github.com>
@coderabbitai

coderabbitai Bot commented Jun 21, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Removes the per-account Discord proxy URL emission from the template resolver by deleting the proxyUrl helper and its DEFAULT_PROXY_HOST/DEFAULT_PROXY_PORT constants, making discordProxyUrl always resolve to undefined. All unit and E2E tests are updated to assert that the Discord account proxy field is empty and gateway routing defers to OpenClaw's top-level managed proxy.

Changes

Discord per-account proxy removal

Layer / File(s) Summary
Template resolver: drop per-account proxy computation
src/lib/messaging/channels/discord/template-resolver.ts
Replaces the "discordProxyUrl" case's computed proxy URL with resolvedRenderTemplateReference(undefined), removes proxyUrl(env), DEFAULT_PROXY_HOST, DEFAULT_PROXY_PORT, and the now-unused nonEmptyString import.
Unit and config-gen tests: assert proxy is undefined
test/discord-template-resolver-proxy.test.ts, test/generate-openclaw-config.test.ts
Updates discordProxyUrl resolver tests to expect value: undefined in all env scenarios, and changes five assertion sites in the config-generation tests from a concrete proxy URL to undefined for config.channels.discord.accounts.default.proxy, with associated test description renames.
E2E script: assert empty account proxy and correct managed proxy URL
test/e2e/test-messaging-providers.sh
Rewrites M9b comments to document gateway-only managed proxy routing, and changes the assertion to require account.proxy to be empty while proxy.proxyUrl equals the expected managed proxy URL.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

  • NVIDIA/NemoClaw#5248: Directly conflicts with this PR — it changes resolveDiscordTemplateReference("discordProxyUrl", ...) to compute and return a per-account sandbox proxy URL, the exact opposite of what this PR removes.
  • NVIDIA/NemoClaw#5391: Modifies the same test-messaging-providers.sh Discord gateway proxy-wiring assertion block (M9b), changing expected values for channels.discord.accounts.default.proxy vs proxy.proxyUrl.

Suggested labels

bug-fix, integration: discord, area: messaging

Suggested reviewers

  • cv

🐇 No more proxy baked in the Discord stew,
The per-account URL? Gone — adieu, adieu!
OpenClaw's managed proxy takes the wheel,
undefined is the value — now the gateway can heal.
Hop hop, the WebSocket lives anew! 🎉

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: stopping emission of non-loopback per-account proxy for Discord, which directly addresses the core issue documented in #5544.
Linked Issues check ✅ Passed The PR successfully addresses all coding objectives from #5544: removes non-loopback per-account proxy emission, updates template-resolver and config generation tests, and restores reliance on top-level managed proxy for Discord.
Out of Scope Changes check ✅ Passed All changes are directly scoped to fixing the Discord proxy issue: template-resolver updates, test assertions for undefined proxy behavior, and E2E validation of managed proxy routing with no per-account proxy.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands and usage tips.

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

Labels

None yet

Projects

None yet

1 participant