fix(mattermost): prevent duplicate messages when block streaming + threading are active#41362
Conversation
…reading are active Remove replyToId from createBlockReplyPayloadKey so identical content is deduplicated regardless of threading target. Add explicit threading dock to the Mattermost plugin with resolveReplyToMode reading from config (default "all"), and add replyToMode to the Mattermost config schema. Fixes openclaw#41219 Co-Authored-By: Claude Opus 4.6 <[email protected]>
Greptile SummaryThis PR fixes a duplicate message delivery bug in the Mattermost integration introduced in 2026.3.8 (#27744), where enabling both block streaming and threaded replies ( The root cause was that Changes:
Minor note: Confidence Score: 4/5
Last reviewed commit: 3c07c19 |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 3c07c19dca
ℹ️ 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".
… clarity Read replyToMode from the merged per-account config via resolveMattermostAccount so account-level overrides are honored in multi-account setups. Add replyToMode to MattermostAccountConfig type. Rename misleading test to clarify it exercises shouldDropFinalPayloads short-circuit, not payload key dedup. Co-Authored-By: Claude Opus 4.6 <[email protected]>
|
Both review comments addressed in d30e660:
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 36ff94706d
ℹ️ About Codex in GitHub
Your team has set up Codex to 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 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 59789a80f0
ℹ️ About Codex in GitHub
Your team has set up Codex to 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 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| const payloadKey = createBlockReplyContentKey(payload); | ||
| return sentContentKeys.has(payloadKey); |
There was a problem hiding this comment.
Keep reply target in fallback sent-payload matching
When block streaming aborts/timeouts, buildReplyPayloads falls back to final payload delivery but still filters each payload through blockReplyPipeline.hasSentPayload(...); with this change, that check ignores replyToId, so a payload sent to thread A can incorrectly suppress an unsent payload with identical text/media for thread B during fallback recovery. Fresh evidence relative to prior discussion: createBlockReplyPayloadKey still preserves replyToId for delivery dedupe, but hasSentPayload was switched to createBlockReplyContentKey, which removes target identity in the exact fallback path used after aborts.
Useful? React with 👍 / 👎.
…reading are active (openclaw#41362) * fix(mattermost): prevent duplicate messages when block streaming + threading are active Remove replyToId from createBlockReplyPayloadKey so identical content is deduplicated regardless of threading target. Add explicit threading dock to the Mattermost plugin with resolveReplyToMode reading from config (default "all"), and add replyToMode to the Mattermost config schema. Fixes openclaw#41219 Co-Authored-By: Claude Opus 4.6 <[email protected]> * fix(mattermost): address PR review — per-account replyToMode and test clarity Read replyToMode from the merged per-account config via resolveMattermostAccount so account-level overrides are honored in multi-account setups. Add replyToMode to MattermostAccountConfig type. Rename misleading test to clarify it exercises shouldDropFinalPayloads short-circuit, not payload key dedup. Co-Authored-By: Claude Opus 4.6 <[email protected]> * Replies: keep block-pipeline reply targets distinct * Tests: cover block reply target-aware dedupe * Update CHANGELOG.md --------- Co-authored-by: Claude Opus 4.6 <[email protected]> Co-authored-by: Vincent Koc <[email protected]>
Summary
replyToIdfromcreateBlockReplyPayloadKeyso identical content is deduplicated regardless of threading target — threading is a delivery concern, not content identitythreadingdock to the Mattermost plugin withresolveReplyToModereading fromchannels.mattermost.replyToModeconfig (default:"all")replyToModefield to the Mattermost config schema (z.enum(["off", "first", "all"]))Fixes #41219
Test plan
block-reply-pipeline.test.ts— verifies payload key excludesreplyToId, pipeline deduplicates payloads with differentreplyToId, andhasSentPayloadmatches regardless ofreplyToIdmonitor.test.ts— verifiesresolveMattermostReplyRootIdbehavior with block streaming payloadsagent-runner-payloads.test.ts— verifies final payload suppression when pipeline streamed, anddirectlySentBlockKeysdedup ignoresreplyToId🤖 Generated with Claude Code