Description
Socket Mode WebSocket Does Not Work in NemoClaw
NemoClaw sandboxes run inside a network namespace where all outbound traffic must go through the OpenShell proxy.
The Node.js ws (WebSocket) library used by Slack's Bolt SDK does not respect the https_proxy environment variable. When the Slack SDK opens a WebSocket connection to wss-primary.slack.com, it attempts a direct connection that gets blocked by the network namespace (ECONNREFUSED).
Evidence
- REST calls through Node.js https module work (they respect
https_proxy)
apps.connections.open succeeds and returns a valid WSS URL
- Direct WebSocket connection fails with
ECONNREFUSED
- WebSocket connection with an explicit
HttpsProxyAgent succeeds (returns HTTP 400 as expected without a valid ticket, but the tunnel works)
- The Slack Bolt SDK does not pass a proxy agent to its internal WebSocket client
Reproduction Steps
- Go to api.slack.com/apps and click Create New App → From scratch
- Name your app and select your workspace
- Go to Socket Mode → make sure it is OFF (HTTP mode does not use Socket Mode)
- Go to OAuth & Permissions → add these Bot Token Scopes:
- chat:write
- channels:history
- channels:read
- groups:history
- im:history
- im:read
- im:write
- mpim:history
- mpim:read
- mpim:write
- users:read
- app_mentions:read
- assistant:write
- Click Install to Workspace and copy the Bot User OAuth Token (xoxb-...)
- Go to Basic Information → App Credentials → copy the App Token
- Create a custom
Dockerfile to change the openclaw.json file:
FROM ghcr.io/nvidia/openshell-community/sandboxes/openclaw:latest
ARG NEMOCLAW_MODEL
ARG NEMOCLAW_PROVIDER_KEY
ARG NEMOCLAW_INFERENCE_BASE_URL
ARG NEMOCLAW_MESSAGING_CHANNELS_B64
ARG NEMOCLAW_DISABLE_DEVICE_AUTH=1
RUN mkdir -p /sandbox/.openclaw && node -e '\
var c={\
"agents":{"defaults":{"model":{"primary":"inference/nvidia/nemotron-3-super-120b-a12b"}}},\
"models":{"mode":"merge","providers":{"inference":{"baseUrl":"https://inference.local/v1","apiKey":"unused","api":"openai-completions","models":[{"id":"nvidia/nemotron-3-super-120b-a12b","name":"inference/nvidia/nemotron-3-super-120b-a12b","reasoning":false,"input":["text"],"cost":{"input":0,"output":0,"cacheRead":0,"cacheWrite":0},"contextWindow":131072,"maxTokens":4096}]}}},\
"channels":{"defaults":{},\
"slack":{\
"enabled":true,\
"mode":"socket",\
"accounts":{"default":{"botToken":"xoxb-YOUR-BOT-TOKEN","appToken":"xapp-1-YOUR-APP-TOKEN","enabled":true}},\
"dm":{"enabled":true,"policy":"open","allowFrom":["*"],"groupEnabled":true},\
"groupPolicy":"open",\
"channels":{}\
}\
},\
"gateway":{"mode":"local","controlUi":{"allowInsecureAuth":true,"dangerouslyDisableDeviceAuth":true,"allowedOrigins":["http://127.0.0.1:18789"]},"trustedProxies":["127.0.0.1","::1"],"auth":{"token":"SOME_TOKEN"}},\
"tools":{"web":{"search":{"enabled":true,"provider":"brave"},"fetch":{"enabled":true}}},\
"plugins":{"entries":{"brave":{"config":{"webSearch":{"apiKey":"openshell:resolve:env:BRAVE_API_KEY"}},"enabled":true}}},\
"wizard":{"lastRunAt":"2026-04-14T10:21:10.937Z","lastRunVersion":"2026.4.2","lastRunCommand":"doctor","lastRunMode":"local"},\
"meta":{"lastTouchedVersion":"2026.4.2","lastTouchedAt":"2026-04-14T10:21:11.018Z"}\
};\
require("fs").writeFileSync("/sandbox/.openclaw/openclaw.json",JSON.stringify(c,null,2));'
| Placeholder |
Substitution |
| xapp-1-YOUR-APP-TOKEN |
Slack app → Basic Information → App Credentials → App-level token |
| xoxb-YOUR-BOT-TOKEN |
Slack app → OAuth & Permissions → Bot User OAuth Token |
| SOME_TOKEN |
Run openssl rand -hex 32 on your host |
Environment
Nvidia launchpad:
Tailored for NVIDIA LaunchPad VMs:
- Ubuntu 24.04 LTS
- NVIDIA H100 80GB + Driver 580.x + CUDA 13.0
- Docker 29.x pre-installed
- cgroup v2 active (requires fixes for OpenShell's embedded k3s)
- NVIDIA Container Toolkit CLI version 1.19.0
- Nemoclaw v0.15.0
Debug Output
Logs
No debug or tarball from those command was gotten. These are the ones got from inside the sandbox itself or from within the openclaw /tmp/openclaw/
## 1. Socket Mode starts but immediately fails (repeating every ~5 seconds):
[slack] [default] starting provider
[ERROR] socket-mode:SlackWebSocket:1 WebSocket error occurred:
[ERROR] socket-mode:SocketModeClient:0 WebSocket error! Error
[ERROR] socket-mode:SlackWebSocket:2 WebSocket error occurred:
[ERROR] socket-mode:SocketModeClient:0 WebSocket error! Error
## 2. The REST call to apps.connections.open works via the proxy (Node.js respects https_proxy):
sandbox@emuclaw:~$ node -e "..." (apps.connections.open)
{"ok":true,"url":"wss:\/\/wss-primary.slack.com\/link\/?ticket=e97cf34e-4b06-4b26-bb30-b6579a282288&app_id=cc4041895ba382a65e46f4fb87c6a5ea275aa14c22dfac47d2283e4a991c95f8"}
## 3. Direct WebSocket connection fails — sandbox blocks all direct outbound (ECONNREFUSED):
sandbox@emuclaw:~$ node -e "const WS = require('.../ws'); const ws = new WS('wss://wss-primary.slack.com'); ..."
WS ERROR: ECONNREFUSED
## 4. WebSocket with explicit HttpsProxyAgent works (tunnel succeeds, 400 is expected without valid ticket):
sandbox@emuclaw:~$ node -e "const WS = require('.../ws'); const {HttpsProxyAgent} = require('.../https-proxy-agent'); const agent = new HttpsProxyAgent('http://10.200.0.1:3128'); const ws = new WS('wss://wss-primary.slack.com', {agent}); ..."
WS ERROR: Unexpected server response: 400 undefined
## 5. The proxy environment variables are set but ws library ignores them:
sandbox@emuclaw:~$ echo "https_proxy=$https_proxy"
https_proxy=http://10.200.0.1:3128
Checklist
Description
Socket Mode WebSocket Does Not Work in NemoClaw
NemoClaw sandboxes run inside a network namespace where all outbound traffic must go through the OpenShell proxy.
The Node.js ws (WebSocket) library used by Slack's Bolt SDK does not respect the
https_proxyenvironment variable. When the Slack SDK opens a WebSocket connection towss-primary.slack.com, it attempts a direct connection that gets blocked by the network namespace (ECONNREFUSED).Evidence
https_proxy)apps.connections.opensucceeds and returns a valid WSS URLECONNREFUSEDHttpsProxyAgentsucceeds (returns HTTP 400 as expected without a valid ticket, but the tunnel works)Reproduction Steps
Dockerfileto change theopenclaw.jsonfile:Environment
Nvidia launchpad:
Tailored for NVIDIA LaunchPad VMs:
Debug Output
Logs
Checklist