Environment:
- OpenClaw version: 2026.2.21 (@openclaw/mattermost plugin)
- Install method: local (npm global install)
- OS: Ubuntu 24.04 LTS
- Model setup: ChatGPT OAuth (OpenClaw native gateway)
Description:
Setting replyToMode: \"off\" in the Mattermost channel config does not prevent thread replies. When an incoming message has a root_id (sent as a reply inside a Mattermost thread), the gateway extracts that root_id and passes it through to the outgoing POST request — ignoring the mode setting entirely. This causes the Mattermost API to reject the reply and the message is never delivered.
Steps to Reproduce:
- Configure a Mattermost channel with
replyToMode: \"off\"
- Send a message to the bot as a reply inside an existing Mattermost thread (message has a non-empty
root_id)
- Bot generates a response but delivery fails
Expected Behavior:
replyToMode: \"off\" posts all replies as top-level channel messages unconditionally — regardless of whether the incoming message was part of a thread.
Actual Behavior:
Bot fails to deliver reply. Mattermost returns 400 Bad Request: Invalid RootId parameter.
Logs / Evidence:
[mattermost] final reply failed: Error: Mattermost API 400 Bad Request: Invalid RootId parameter.
Root Cause (identified):
In resolveMattermostEffectiveReplyToId (monitor.ts), the replyToMode check is short-circuited when threadRootId is set — it returns the thread root immediately without ever checking the mode:
// current — replyToMode bypassed for threaded messages
const threadRootId = params.threadRootId?.trim();
if (threadRootId) {
return threadRootId; // replyToMode never reached
}
return params.replyToMode === "all" || params.replyToMode === "first" ? postId : undefined;
One-line fix:
if (threadRootId && params.replyToMode !== "off") {
return threadRootId;
}
This makes replyToMode: \"off\" unconditionally suppress thread replies as documented/expected.
Environment:
Description:
Setting
replyToMode: \"off\"in the Mattermost channel config does not prevent thread replies. When an incoming message has aroot_id(sent as a reply inside a Mattermost thread), the gateway extracts thatroot_idand passes it through to the outgoing POST request — ignoring the mode setting entirely. This causes the Mattermost API to reject the reply and the message is never delivered.Steps to Reproduce:
replyToMode: \"off\"root_id)Expected Behavior:
replyToMode: \"off\"posts all replies as top-level channel messages unconditionally — regardless of whether the incoming message was part of a thread.Actual Behavior:
Bot fails to deliver reply. Mattermost returns
400 Bad Request: Invalid RootId parameter.Logs / Evidence:
Root Cause (identified):
In
resolveMattermostEffectiveReplyToId(monitor.ts), thereplyToModecheck is short-circuited whenthreadRootIdis set — it returns the thread root immediately without ever checking the mode:One-line fix:
This makes
replyToMode: \"off\"unconditionally suppress thread replies as documented/expected.