You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[bug] Slack Socket Mode crashes on boot with invalid_auth — appToken missing from baked openclaw.json; token resolution also appears broken
Summary
NemoClaw v0.0.20 onboarding with the Slack messaging channel selected produces a
sandbox that cannot connect to Slack. On every boot the gateway crashes with
an unhandled promise rejection:
[openclaw] Unhandled promise rejection: Error: An API error occurred: invalid_auth
at platformErrorFromResult (.../@slack/web-api/src/errors.ts:119:5)
at WebClient.apiCall (.../@slack/web-api/src/WebClient.ts:405:36)
The crash takes the entire gateway down (and with it, the dashboard at :18789), so the sandbox is unusable whenever Slack credentials are present.
Environment
NemoClaw: v0.0.20
Host: macOS 26.3.1 on Apple M4 Mac Mini (16 GB unified memory)
Runtime: Docker Desktop
Inference provider: ollama-local / gemma4:e4b
Messaging channel: slack (Socket Mode)
Policy tier: Balanced + slack preset applied
Install path: interactive nemoclaw onboard, with later nemoclaw nemo rebuild and nemoclaw onboard --non-interactive --resume --recreate-sandbox iterations while debugging.
Two issues that together cause the crash
Issue 1 — generated openclaw.json is missing appToken
The Dockerfile generates the baked openclaw.json from NEMOCLAW_MESSAGING_CHANNELS_B64. The Python block at Dockerfile:245:
Result: the baked /sandbox/.openclaw/openclaw.json has only botToken for
Slack. No appToken. @slack/bolt Socket Mode cannot initialize without an
App-Level Token, so apps.connections.open fails immediately.
i.e. the literal marker strings, not the real tokens. For Brave, the same
marker appears in openclaw.json but the sandbox env has the real value
(because openshell sandbox create is called with --env BRAVE_API_KEY=BSA... directly). For Slack there is no equivalent — the openshell sandbox create command records:
No SLACK_BOT_TOKEN=... or SLACK_APP_TOKEN=... injected. The nemo-slack-bridge and nemo-slack-app OpenShell providers are registered
with credential keys, but setting them via:
does not cause the L7 proxy to substitute the placeholder strings. Requests
reach slack.com with Authorization: Bearer openshell:resolve:env:SLACK_BOT_TOKEN
(inferred from the invalid_auth response; the real tokens are verified valid
via curl from the host).
Gateway container env is also empty of slack tokens:
So neither the sandbox env, nor the proxy container env, nor the openclaw.json
itself contains the real token values, despite nemoclaw credentials list
showing both tokens stored.
Messaging: Slack only, paste valid xoxb- and xapp- tokens
Policy tier: Balanced; verify slack preset is toggled on
Wait for the sandbox to come up.
Observe (inside sandbox):
cat /sandbox/.openclaw/openclaw.json | jq '.channels.slack'
# → only botToken, no appToken
env | grep SLACK
# → openshell:resolve:env:... literals, not real tokens
Tail the sandbox gateway log — crash loop on invalid_auth within seconds of [slack] [default] starting provider.
Expected behavior
openclaw.json includes appToken when Slack is selected, so Socket Mode
has what it needs.
openshell:resolve:env:* placeholders are resolved (either at build time
when tokens are baked, at sandbox-create env injection time like Brave, or
at egress-proxy rewrite time) so that Authorization: Bearer <real-token>
reaches Slack.
Dashboard stays up on boot regardless of whether Slack auth succeeds
(a single channel failure should not crash the entire gateway — the
unhandled promise rejection should be caught and the channel marked
unavailable in the UI).
Local patch I applied (partial fix)
Edited Dockerfile line 247 to append an appToken spread for slack:
- **({'dmPolicy': ...} if ... else {})}}}+ **({'dmPolicy': ...} if ... else {}), **({'appToken': 'openshell:resolve:env:SLACK_APP_TOKEN'} if ch == 'slack' else {})}}}
After rebuild, openclaw.json contains both botToken and appToken, but
the runtime invalid_auth persists because Issue 2 is unresolved — the proxy
or sandbox env never receives the real token values.
Additional notes / related papercuts surfaced while debugging
Race condition on sandbox boot. Policy presets are applied AFTER openshell sandbox create, so on first boot the sandbox egress denies slack.com:443 and the gateway crashes with Failed to establish tunnel to slack.com:443 ... HTTP/1.1 403 Forbidden. By the time the slack preset
lands, the process has exited. A subsequent manual restart of the gateway
does reach Slack, but only to hit Issue 2.
Rebuild refuses when sandbox is already dead.nemoclaw nemo rebuild
exits with "Sandbox 'nemo' is not running. Cannot back up state. Start it
first or recreate with nemoclaw onboard --recreate-sandbox." This is
accurate messaging but traps users whose sandbox crashed on the Slack bug
above — they now need the slower onboard-recreate path to recover.
credentials list has no add counterpart. Once a credential is
missing, the only documented way to re-enter it is to re-run nemoclaw onboard, which forces another rebuild. A nemoclaw credentials set KEY (reading from stdin silently) would help a lot — especially since
the current onboarding flow re-pulls the Docker validation image and risks
the macOS keychain lock issue ([WSL2] NemoClaw sandbox cannot reach Windows-hosted Ollama — local inference path blocked (relates to #305, #315, #246) #336 is adjacent) over SSH sessions.
Dashboard exits with gateway crash. Because the dashboard is served by
the same node process as the Slack provider, one unhandled promise
rejection takes the whole UI down. Users then can't even see the failure
state in the dashboard — the port is unresponsive.
Happy to contribute a PR for Issue 1 (the Dockerfile appToken fix is a
one-liner). Issue 2 likely needs someone with visibility into the openshell:resolve:env:* resolution path to point me at the right surface.
[bug] Slack Socket Mode crashes on boot with
invalid_auth—appTokenmissing from baked openclaw.json; token resolution also appears brokenSummary
NemoClaw v0.0.20 onboarding with the Slack messaging channel selected produces a
sandbox that cannot connect to Slack. On every boot the gateway crashes with
an unhandled promise rejection:
The crash takes the entire gateway down (and with it, the dashboard at
:18789), so the sandbox is unusable whenever Slack credentials are present.Environment
ollama-local/gemma4:e4bslack(Socket Mode)slackpreset appliednemoclaw onboard, with laternemoclaw nemo rebuildandnemoclaw onboard --non-interactive --resume --recreate-sandboxiterations while debugging.Two issues that together cause the crash
Issue 1 — generated
openclaw.jsonis missingappTokenThe Dockerfile generates the baked
openclaw.jsonfromNEMOCLAW_MESSAGING_CHANNELS_B64. The Python block atDockerfile:245:Result: the baked
/sandbox/.openclaw/openclaw.jsonhas onlybotTokenforSlack. No
appToken.@slack/boltSocket Mode cannot initialize without anApp-Level Token, so
apps.connections.openfails immediately.Observed baked config:
Issue 2 —
openshell:resolve:env:*placeholders never resolve to real tokensEven after patching the Dockerfile to also emit
"appToken": "openshell:resolve:env:SLACK_APP_TOKEN", the Slack SDK stillreceives
invalid_auth.Inside the sandbox:
$ env | grep SLACK SLACK_BOT_TOKEN=openshell:resolve:env:SLACK_BOT_TOKEN SLACK_APP_TOKEN=openshell:resolve:env:SLACK_APP_TOKENi.e. the literal marker strings, not the real tokens. For Brave, the same
marker appears in
openclaw.jsonbut the sandbox env has the real value(because
openshell sandbox createis called with--env BRAVE_API_KEY=BSA...directly). For Slack there is no equivalent — theopenshell sandbox createcommand records:No
SLACK_BOT_TOKEN=...orSLACK_APP_TOKEN=...injected. Thenemo-slack-bridgeandnemo-slack-appOpenShell providers are registeredwith credential keys, but setting them via:
does not cause the L7 proxy to substitute the placeholder strings. Requests
reach
slack.comwithAuthorization: Bearer openshell:resolve:env:SLACK_BOT_TOKEN(inferred from the
invalid_authresponse; the real tokens are verified validvia
curlfrom the host).Gateway container env is also empty of slack tokens:
So neither the sandbox env, nor the proxy container env, nor the openclaw.json
itself contains the real token values, despite
nemoclaw credentials listshowing both tokens stored.
Reproduction
curl -fsSL https://www.nvidia.com/nemoclaw.sh | bashnemoclaw onboardgemma4:e4bxoxb-andxapp-tokensslackpreset is toggled oninvalid_authwithin seconds of[slack] [default] starting provider.Expected behavior
openclaw.jsonincludesappTokenwhen Slack is selected, so Socket Modehas what it needs.
openshell:resolve:env:*placeholders are resolved (either at build timewhen tokens are baked, at sandbox-create env injection time like Brave, or
at egress-proxy rewrite time) so that
Authorization: Bearer <real-token>reaches Slack.
(a single channel failure should not crash the entire gateway — the
unhandled promise rejection should be caught and the channel marked
unavailable in the UI).
Local patch I applied (partial fix)
Edited
Dockerfileline 247 to append anappTokenspread for slack:After rebuild,
openclaw.jsoncontains bothbotTokenandappToken, butthe runtime invalid_auth persists because Issue 2 is unresolved — the proxy
or sandbox env never receives the real token values.
Additional notes / related papercuts surfaced while debugging
Race condition on sandbox boot. Policy presets are applied AFTER
openshell sandbox create, so on first boot the sandbox egress deniesslack.com:443and the gateway crashes withFailed to establish tunnel to slack.com:443 ... HTTP/1.1 403 Forbidden. By the time theslackpresetlands, the process has exited. A subsequent manual restart of the gateway
does reach Slack, but only to hit Issue 2.
Rebuild refuses when sandbox is already dead.
nemoclaw nemo rebuildexits with "Sandbox 'nemo' is not running. Cannot back up state. Start it
first or recreate with
nemoclaw onboard --recreate-sandbox." This isaccurate messaging but traps users whose sandbox crashed on the Slack bug
above — they now need the slower onboard-recreate path to recover.
credentials listhas noaddcounterpart. Once a credential ismissing, the only documented way to re-enter it is to re-run
nemoclaw onboard, which forces another rebuild. Anemoclaw credentials set KEY(reading from stdin silently) would help a lot — especially sincethe current onboarding flow re-pulls the Docker validation image and risks
the macOS keychain lock issue ([WSL2] NemoClaw sandbox cannot reach Windows-hosted Ollama — local inference path blocked (relates to #305, #315, #246) #336 is adjacent) over SSH sessions.
Dashboard exits with gateway crash. Because the dashboard is served by
the same node process as the Slack provider, one unhandled promise
rejection takes the whole UI down. Users then can't even see the failure
state in the dashboard — the port is unresponsive.
Happy to contribute a PR for Issue 1 (the Dockerfile
appTokenfix is aone-liner). Issue 2 likely needs someone with visibility into the
openshell:resolve:env:*resolution path to point me at the right surface.References
/usr/local/lib/node_modules/openclaw/dist/zod-schema.providers-core-*.js(shows
appToken: SecretInputSchema.optional().register(sensitive))