Skip to content

[Bug]: Mattermost native slash commands return 401 on every callback after 6.11 plugin externalization, even after clean re-registration #98740

Description

@KelTech-Services

Bug type: Regression (worked before, now fails)

Summary
After updating to 2026.6.11, which externalizes the previously-bundled Mattermost plugin to @openclaw/mattermost, all native /oc_* slash commands return 401 Unauthorized: invalid command token. on every invocation. Normal DMs and @mentions work fine — only native slash command callbacks are rejected. Slash commands worked correctly on 2026.6.10 with an identical config.

Environment

  • OpenClaw 2026.6.11 (e085fa1)
  • @openclaw/mattermost 2026.6.11 (externalized; installed to ~/.openclaw/npm/projects/openclaw-mattermost-*)
  • Codex app-server harness, macOS (Apple Silicon), single Mattermost account (default)
  • Callback via HTTPS reverse proxy: callbackUrl: https://<host>/api/channels/mattermost/command

What I've confirmed

  1. The POST reaches OpenClaw. Reverse-proxy access log shows each slash callback forwarded to the gateway; the gateway itself returns 401 (not the proxy). Requests returned 200 until the 6.11 update, 401 immediately after.
  2. All Mattermost-side command fields are correct. For each command, MM has method: "P", correct url, team_id, trigger, and a present token — satisfying every field check in validateMattermostSlashCommandToken (slash-state-*.js, ~line 1660).
  3. A clean re-registration does not fix it. With the gateway stopped, I deleted all oc_* commands via the MM API (verified 0 remain), then started the gateway. OpenClaw created all 48 commands fresh (logged registered command /oc_status (id=…)) with matching id/token/method/url. Callbacks still 401.
  4. Toggling commands.native false→restart→true→restart does not help (commands are reused as "already registered").

Handler path
Installed 6.11 handler dist/slash-state-*.js returns 401 at three points; the relevant one for a valid inbound command is the token/command resolution in resolveSlashHandlerForToken (checks state.commandTokens.has(token)) with fallback to resolveSlashHandlerForCommand. Both apparently miss despite a fresh registration, so the in-memory commandTokens/registeredCommands set for the account does not match the token Mattermost transmits in the callback body.

What I could not capture
Byte-level comparison of the token in the live callback POST body vs. OpenClaw's in-memory commandTokens — the host is a standard (non-root) user, so packet capture isn't available, and I did not want to run a code shim on a production gateway. A maintainer able to log the inbound payload.token alongside the resolved account's commandTokens at the 401 branch should see the mismatch directly.

Suspected cause
Regression in the externalized @openclaw/mattermost 6.11 registration/token-set population path. (Externalization regressions have precedent in this range, e.g. #95658.)

Config (relevant)

"commands": { "native": true, "nativeSkills": true,
  "callbackUrl": "https://<host>/api/channels/mattermost/command",
  "callbackPath": "/api/channels/mattermost/command" }

Metadata

Metadata

Assignees

Labels

P1High-priority user-facing bug, regression, or broken workflow.clawsweeper:needs-live-reproClawSweeper needs live local, crabbox, or manual validation to confirm this issue.clawsweeper:needs-maintainer-reviewClawSweeper marked this issue as needing maintainer review before automation.clawsweeper:no-new-fix-prClawSweeper does not recommend queueing a new automated fix PR for this issue.impact:message-lossChannel message delivery can be lost, duplicated, or misrouted.issue-rating: 🐚 platinum hermitGood issue quality with a plausible reproduction path needing some confirmation.

Type

No type

Fields

Priority

None yet

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions