Skip to content

fix(mattermost): read replyTo param in plugin handleAction send#41176

Merged
mukhtharcm merged 2 commits intoopenclaw:mainfrom
hnykda:fix/mattermost-replyto-handleaction
Mar 10, 2026
Merged

fix(mattermost): read replyTo param in plugin handleAction send#41176
mukhtharcm merged 2 commits intoopenclaw:mainfrom
hnykda:fix/mattermost-replyto-handleaction

Conversation

@hnykda
Copy link
Copy Markdown
Contributor

@hnykda hnykda commented Mar 9, 2026

Summary

The Mattermost plugin's handleAction reads params.replyToId for the send action, but the message tool passes the reply target as params.replyTo. This causes message(replyTo=<id>) to create top-level posts (root_id: "") instead of threaded replies.

Root cause

  1. Message tool sends replyTo parameter
  2. handleSendAction (message-action-runner.ts) reads params.replyTo into a local variable replyToId
  3. tryHandleWithPluginAction is called, passing the raw params object to the plugin
  4. Mattermost plugin's handleAction reads params.replyToId — which is undefined because the property is named replyTo, not replyToId
  5. sendMessageMattermost is called with replyToId: undefined → post created with empty root_id

The core path (non-plugin) works correctly because executeSendAction receives the extracted replyToId as a separate argument.

Fix

Check both params.replyToId and params.replyTo in the Mattermost plugin's send handler.

Testing

Tested on a self-hosted v2026.3.8 instance:

  • Before fix: message(replyTo=<id>)root_id: "" (top-level post)
  • After fix: message(replyTo=<id>)root_id: <id> (threaded reply, confirmed via API and UI)

Fixes #40924

@hnykda
Copy link
Copy Markdown
Contributor Author

hnykda commented Mar 9, 2026

Manually verified on a self-hosted v2026.3.8 instance:

  1. Agent sends message(action=send, target=<channel>, replyTo=<message_id>, message="test reply")
  2. Before patch: Mattermost API shows root_id: "" — reply appears as top-level message
  3. After patch: Mattermost API shows root_id: <message_id> — reply correctly appears nested in thread, reply_count increments on parent

Both the API response and the Mattermost UI confirm threaded replies work correctly after this fix.

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Mar 9, 2026

Greptile Summary

This PR fixes a parameter name mismatch in the Mattermost plugin that caused message(replyTo=<id>) calls to create top-level posts instead of threaded replies. The root cause is that handleSendAction in message-action-runner.ts reads params.replyTo but never writes it back as params.replyToId, so the Mattermost plugin (which received the raw params object via tryHandleWithPluginAction) could never find the reply target under the name it was looking for.

  • Fix (extensions/mattermost/src/channel.ts): The send handler now checks params.replyToId first and falls back to params.replyTo, matching how the message tool actually names the parameter. The logic is correct and minimal.
  • Broader exposure: Several other channel plugins (extensions/slack/src/channel.ts:87, extensions/imessage/src/channel.ts:79, extensions/feishu/src/outbound.ts:50, extensions/msteams/src/attachments/graph.ts:73) also read params.replyToId exclusively and would be affected by the same parameter naming inconsistency. This PR does not address those, but that is a separate concern.

Confidence Score: 4/5

  • This PR is safe to merge — the change is minimal, well-scoped, and directly fixes a confirmed regression in threaded Mattermost replies.
  • The fix is correct and the root cause is well-understood. Score is 4 rather than 5 because the same params.replyToId vs params.replyTo mismatch exists in other channel plugins (Slack, iMessage, Feishu, MS Teams) that were not addressed here, leaving them potentially affected by the same bug.
  • No files in this PR require special attention, but extensions/slack/src/channel.ts, extensions/imessage/src/channel.ts, extensions/feishu/src/outbound.ts, and extensions/msteams/src/attachments/graph.ts may have the same upstream issue and are worth a follow-up.

Last reviewed commit: 39cf1d8

@openclaw-barnacle openclaw-barnacle bot added docs Improvements or additions to documentation channel: discord Channel integration: discord channel: googlechat Channel integration: googlechat channel: telegram Channel integration: telegram app: ios App: ios app: macos App: macos app: web-ui App: web-ui gateway Gateway runtime extensions: memory-core Extension: memory-core cli CLI command changes commands Command implementations docker Docker and sandbox tooling agents Agent runtime and tooling channel: feishu Channel integration: feishu extensions: acpx size: XL and removed size: XS labels Mar 10, 2026
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d739f2eb65

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +138 to +140
const revision = state?.revision ?? 0;
if (state) {
pruneExpired(state, nowMs);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Return post-prune revision from pending drain

drainNodePendingWork snapshots revision before calling pruneExpired, but pruneExpired increments state.revision when expired items are removed. In the common polling path where only expiration changed the queue, the method returns a stale revision, so clients that rely on revision changes can miss that pending work mutated and keep operating on outdated state.

Useful? React with 👍 / 👎.

Comment on lines +152 to +153
if (noProxyValue === "*") {
return true;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Recognize wildcard no_proxy entries during bypass check

The bypass helper only treats wildcard as valid when the entire env var is exactly "*". When no_proxy is provided as a list (for example "*,api.telegram.org"), the * entry is not recognized, so Telegram is misclassified as proxied. That disables sticky IPv4 fallback for env-proxy mode even though the request is actually direct via NO_PROXY, which can leave Telegram fetches failing on dual-stack/IPv6-unreachable networks.

Useful? React with 👍 / 👎.

@mukhtharcm mukhtharcm force-pushed the fix/mattermost-replyto-handleaction branch from d739f2e to 2fe21ea Compare March 10, 2026 07:17
@openclaw-barnacle openclaw-barnacle bot removed docs Improvements or additions to documentation channel: discord Channel integration: discord channel: googlechat Channel integration: googlechat channel: telegram Channel integration: telegram app: ios App: ios app: macos App: macos labels Mar 10, 2026
@openclaw-barnacle openclaw-barnacle bot added size: S and removed cli CLI command changes commands Command implementations docker Docker and sandbox tooling agents Agent runtime and tooling channel: feishu Channel integration: feishu extensions: acpx size: XL labels Mar 10, 2026
@mukhtharcm mukhtharcm self-assigned this Mar 10, 2026
hnykda and others added 2 commits March 10, 2026 07:28
The Mattermost plugin's handleAction reads params.replyToId for the
send action, but the message tool passes the reply target as
params.replyTo. The core handleSendAction (message-action-runner.ts)
extracts params.replyTo into a local variable and passes it to
executeSendAction, but never writes it back onto the params object
as replyToId. Since the plugin intercepts before executeSendAction
runs, it always sees replyToId as undefined.

This causes message(replyTo=<id>) to create top-level Mattermost
posts with root_id="" instead of threaded replies.

Fix: check both params.replyToId and params.replyTo in the plugin's
send handler.

Fixes openclaw#40924
@mukhtharcm mukhtharcm force-pushed the fix/mattermost-replyto-handleaction branch from 2fe21ea to 33cac4c Compare March 10, 2026 07:42
@mukhtharcm mukhtharcm merged commit 450d49e into openclaw:main Mar 10, 2026
28 checks passed
@mukhtharcm
Copy link
Copy Markdown
Member

Merged via squash.

Thanks @hnykda!

@hnykda
Copy link
Copy Markdown
Contributor Author

hnykda commented Mar 10, 2026

Appreciated!

@hnykda hnykda deleted the fix/mattermost-replyto-handleaction branch March 10, 2026 07:50
mrosmarin added a commit to mrosmarin/openclaw that referenced this pull request Mar 10, 2026
* main: (43 commits)
  docs: add openclaw#42173 to CHANGELOG — strip leaked model control tokens (openclaw#42216)
  Agents: align onPayload callback and OAuth imports
  docs: add Tengji (George) Zhang to maintainer table (openclaw#42190)
  fix: strip leaked model control tokens from user-facing text (openclaw#42173)
  Changelog: add unreleased March 9 entries
  chore: add .dev-state to .gitignore (openclaw#41848)
  fix(agents): avoid duplicate same-provider cooldown probes in fallback runs (openclaw#41711)
  fix(mattermost): preserve markdown formatting and native tables (openclaw#18655)
  feat(acp): add resumeSessionId to sessions_spawn for ACP session resume (openclaw#41847)
  ACPX: bump bundled acpx to 0.1.16 (openclaw#41975)
  mattermost: fix DM media upload for unprefixed user IDs (openclaw#29925)
  fix(msteams): use General channel conversation ID as team key for Bot Framework compatibility (openclaw#41838)
  fix(mattermost): read replyTo param in plugin handleAction send (openclaw#41176)
  fix(sandbox): pass real workspace to sessions_spawn when workspaceAccess is ro (openclaw#40757)
  fix(ui): replace Manual RPC text input with sorted method dropdown (openclaw#14967)
  CI: select Swift 6.2 toolchain for CodeQL (openclaw#41787)
  fix(agents): forward memory flush write path (openclaw#41761)
  fix(telegram): move network fallback to resolver-scoped dispatchers (openclaw#40740)
  fix(security): harden replaceMarkers() to catch space/underscore boundary marker variants (openclaw#35983)
  fix(web-search): recover OpenRouter Perplexity citations from message annotations (openclaw#40881)
  ...
Moshiii pushed a commit to Moshiii/openclaw that referenced this pull request Mar 11, 2026
…claw#41176)

Merged via squash.

Prepared head SHA: 33cac4c
Co-authored-by: hnykda <[email protected]>
Co-authored-by: mukhtharcm <[email protected]>
Reviewed-by: @mukhtharcm
Moshiii pushed a commit to Moshiii/openclaw that referenced this pull request Mar 11, 2026
…claw#41176)

Merged via squash.

Prepared head SHA: 33cac4c
Co-authored-by: hnykda <[email protected]>
Co-authored-by: mukhtharcm <[email protected]>
Reviewed-by: @mukhtharcm
frankekn pushed a commit to MoerAI/openclaw that referenced this pull request Mar 11, 2026
…claw#41176)

Merged via squash.

Prepared head SHA: 33cac4c
Co-authored-by: hnykda <[email protected]>
Co-authored-by: mukhtharcm <[email protected]>
Reviewed-by: @mukhtharcm
frankekn pushed a commit to Effet/openclaw that referenced this pull request Mar 11, 2026
…claw#41176)

Merged via squash.

Prepared head SHA: 33cac4c
Co-authored-by: hnykda <[email protected]>
Co-authored-by: mukhtharcm <[email protected]>
Reviewed-by: @mukhtharcm
frankekn pushed a commit to ImLukeF/openclaw that referenced this pull request Mar 11, 2026
…claw#41176)

Merged via squash.

Prepared head SHA: 33cac4c
Co-authored-by: hnykda <[email protected]>
Co-authored-by: mukhtharcm <[email protected]>
Reviewed-by: @mukhtharcm
dominicnunez pushed a commit to dominicnunez/openclaw that referenced this pull request Mar 11, 2026
…claw#41176)

Merged via squash.

Prepared head SHA: 33cac4c
Co-authored-by: hnykda <[email protected]>
Co-authored-by: mukhtharcm <[email protected]>
Reviewed-by: @mukhtharcm
dhoman pushed a commit to dhoman/chrono-claw that referenced this pull request Mar 11, 2026
…claw#41176)

Merged via squash.

Prepared head SHA: 33cac4c
Co-authored-by: hnykda <[email protected]>
Co-authored-by: mukhtharcm <[email protected]>
Reviewed-by: @mukhtharcm
ahelpercn pushed a commit to ahelpercn/openclaw that referenced this pull request Mar 12, 2026
…claw#41176)

Merged via squash.

Prepared head SHA: 33cac4c
Co-authored-by: hnykda <[email protected]>
Co-authored-by: mukhtharcm <[email protected]>
Reviewed-by: @mukhtharcm
Ruijie-Ysp pushed a commit to Ruijie-Ysp/clawdbot that referenced this pull request Mar 12, 2026
…claw#41176)

Merged via squash.

Prepared head SHA: 33cac4c
Co-authored-by: hnykda <[email protected]>
Co-authored-by: mukhtharcm <[email protected]>
Reviewed-by: @mukhtharcm
qipyle pushed a commit to qipyle/openclaw that referenced this pull request Mar 12, 2026
…claw#41176)

Merged via squash.

Prepared head SHA: 33cac4c
Co-authored-by: hnykda <[email protected]>
Co-authored-by: mukhtharcm <[email protected]>
Reviewed-by: @mukhtharcm
senw-developers pushed a commit to senw-developers/va-openclaw that referenced this pull request Mar 17, 2026
…claw#41176)

Merged via squash.

Prepared head SHA: 33cac4c
Co-authored-by: hnykda <[email protected]>
Co-authored-by: mukhtharcm <[email protected]>
Reviewed-by: @mukhtharcm
V-Gutierrez pushed a commit to V-Gutierrez/openclaw-vendor that referenced this pull request Mar 17, 2026
…claw#41176)

Merged via squash.

Prepared head SHA: 33cac4c
Co-authored-by: hnykda <[email protected]>
Co-authored-by: mukhtharcm <[email protected]>
Reviewed-by: @mukhtharcm
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

channel: mattermost Channel integration: mattermost size: S

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Mattermost: Channel-bound sessions cannot thread replies (dispatcher routing bug)

2 participants