Skip to content

Mattermost: block streaming edits single post instead of creating separate messages per text block #87322

Description

@Senseonics-AI

Summary

When block streaming is enabled for Mattermost (blockStreaming: true, blockStreamingDefault: "on", blockStreamingBreak: "text_end"), text blocks between tool calls are not delivered as separate channel messages. Instead, the Mattermost plugin edits a single post in place, causing each text segment to overwrite the previous one. The end result is that only the final text block is visible to the user.

Two distinct issues found through testing

Issue 1: Block streaming does not create separate posts on Mattermost

With block streaming enabled and preview streaming disabled (streaming: "off"), block replies are still delivered by editing a single post rather than creating new Mattermost posts. This differs from Discord where block streaming correctly creates separate messages per text block.

Expected: Each text block flushed at text_end creates a new Mattermost post.
Actual: All text blocks edit the same post. Only the final text is visible.

Config tested:

{
  "agents": { "defaults": {
    "blockStreamingDefault": "on",
    "blockStreamingBreak": "text_end",
    "typingMode": "instant"
  }},
  "channels": { "mattermost": {
    "streaming": "off",
    "blockStreaming": true
  }}
}

Issue 2: Streaming "block" mode accumulates correctly but finalization wipes content

With streaming: "block" (append-style preview), the draft post correctly accumulates all content during generation — interim text, tool progress, and final text are all visible in the post as they arrive. However, when the turn completes, the finalization step replaces the entire accumulated content with only the final text block.

Expected: Finalization preserves the accumulated content (or at minimum, all text blocks from the turn).
Actual: Finalization edits the post to contain only the last text segment. All previously appended content is lost.

Config tested:

{
  "agents": { "defaults": {
    "blockStreamingDefault": "off",
    "typingMode": "instant"
  }},
  "channels": { "mattermost": {
    "streaming": { "mode": "block", "preview": { "toolProgress": true } },
    "blockStreaming": false
  }}
}

This is distinct from #32868

Issue #32868 describes block replies arriving simultaneously after the turn completes (a timing/await issue in the reply pipeline). These issues are about the Mattermost plugin's delivery mechanism:

  • Issue 1: block replies edit one post instead of creating separate posts
  • Issue 2: append-style preview works during generation but finalization replaces accumulated content

Additional configs tested (all exhibit the same behavior)

  • streaming: "partial" + blockStreaming: true — preview streaming takes over, edits one post
  • streaming: "partial" + blockStreaming: true + blockStreamingBreak: "text_end" — same single-post edit
  • streaming: "off" + blockStreaming: false — no streaming at all, only final text delivered
  • streaming: "off" + blockStreaming: true + blockStreamingBreak: "text_end" + blockStreamingCoalesce + typingMode: "instant" (Telegram workaround from Recommend blockStreaming: on for tool-heavy multi-agent setups #48522) — same behavior on Mattermost
  • streaming: "partial" + blockStreamingDefault: "on" + blockStreamingBreak: "message_end" — same behavior

Suggested fixes (two paths)

Path 1 (preferred): Block streaming creates separate Mattermost posts
Make the Mattermost plugin's block reply delivery path call POST /api/v4/posts (create new post) for each block reply instead of PUT /api/v4/posts/{id} (edit existing post). This would match Discord's block streaming behavior where each text segment between tool calls becomes its own message.

Path 2 (alternative): Finalization preserves accumulated content
When streaming: "block" is active, the finalization step should preserve all accumulated text blocks in the post rather than replacing them with only the last text segment. The append-style accumulation during generation already works correctly — the fix would be to not discard that content at finalization.

Environment

  • OpenClaw version: 2026.5.20
  • Mattermost version: 11.6.2 (Team Edition, self-hosted Docker)
  • Channel: Mattermost group channel
  • Agent: tool-heavy (exec, session_status, cron, etc.)

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1High-priority user-facing bug, regression, or broken workflow.clawsweeper:linked-pr-openClawSweeper found an open linked pull request for this issue.clawsweeper:no-new-fix-prClawSweeper does not recommend queueing a new automated fix PR for this issue.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.impact:message-lossChannel message delivery can be lost, duplicated, or misrouted.issue-rating: 🦞 diamond lobsterVery strong issue quality with high-confidence source-level or clear reproduction.

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions