openclaw - ✅(Solved) Fix Discord: streaming chunks break markdown formatting when split occurs inside structured elements [3 pull requests, 1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#63409Fetched 2026-04-09 07:54:06
View on GitHub
Comments
0
Participants
1
Timeline
8
Reactions
0
Participants
Timeline (top)
referenced ×5cross-referenced ×3

Discord message delivery frequently corrupts markdown formatting by splitting chunks at boundaries that land inside structured elements (blockquotes, nested lists, tables, inline code spans). Each chunk renders independently in Discord, so formatting that spans a chunk boundary breaks visually.

This is distinct from existing fragmentation issues (#31679, #24363) which focus on mid-word splits with specific models. This issue affects all models and manifests as structural formatting corruption rather than simple text fragmentation.

Root Cause

Discord message delivery frequently corrupts markdown formatting by splitting chunks at boundaries that land inside structured elements (blockquotes, nested lists, tables, inline code spans). Each chunk renders independently in Discord, so formatting that spans a chunk boundary breaks visually.

This is distinct from existing fragmentation issues (#31679, #24363) which focus on mid-word splits with specific models. This issue affects all models and manifests as structural formatting corruption rather than simple text fragmentation.

Fix Action

Fixed

PR fix notes

PR #63412: fix(discord): propagate blockquote context across chunk boundaries

Description (problem / solution / changelog)

Summary

Fixes #63409

When chunkDiscordText() flushed a chunk in the middle of a blockquote, the next chunk started without the leading > prefix. Discord renders each message independently, so continuation lines appeared as plain text outside the quote block.

Root cause

The chunker already tracks fenced code block state (openFence) and re-seeds the next chunk with the opening fence line on flush. The same treatment was never applied to blockquote prefixes.

Fix

Track the current blockquote prefix (openBlockquote) using the same pattern:

// On flush, re-seed the next chunk with the blockquote prefix
if (openBlockquote && !openFence) {
  current = openBlockquote;
  currentLines = 1;
}

A BLOCKQUOTE_RE helper extracts the prefix including nested levels (> , >> , etc.). The prefix is updated on each line and cleared when a non-blockquote line is encountered.

Behaviour

CaseBeforeAfter
Multi-line > blockquote split at chunk boundaryContinuation lines render as plain textAll lines render inside the quote block
Nested >> blockquote split at boundarySame problemNested level preserved
Fenced code block inside blockquoteUnchangedUnchanged
Non-blockquote contentUnchangedUnchanged

Changed files

  • extensions/discord/src/chunk.ts (added, +302/-0)

PR #63438: fix: preserve tables, blockquotes, and inline formatting across chunk boundaries

Description (problem / solution / changelog)

Fixes #63409

Problem

When OpenClaw delivers messages to Discord, the chunking pipeline splits text at boundaries that can land inside markdown structures. Each chunk renders independently in Discord, so formatting that spans a chunk boundary breaks. Tables get split mid-row, blockquotes lose their > prefix in continuation chunks, and inline formatting (**bold**, \code``) can get orphaned across splits.

Solution

Extends the existing fence-aware chunking pattern (parseFenceSpans() / reopenFence) to handle additional markdown structures:

Tables (src/markdown/table-spans.ts)

  • parseTableSpans() detects contiguous table blocks (header + separator + data rows)
  • Tables are treated as atomic spans - the chunker avoids splitting inside them
  • If a table exceeds the chunk limit, the header + separator are repeated in the continuation chunk via reopenTableHeader

Blockquotes (src/markdown/blockquotes.ts)

  • parseBlockquoteSpans() detects >-prefixed regions
  • When splitting inside a blockquote, reapplyBlockquotePrefix() adds > to every line in the continuation chunk

Inline formatting (src/markdown/inline-formatting.ts)

  • scanUnmatchedInlineMarkers() finds unmatched **, *, ``` at chunk boundaries
  • Closes unmatched markers before the split and reopens them in the next chunk
  • Only scans outside fenced code blocks to avoid false positives

List nesting (src/markdown/lists.ts)

  • detectListContext() scaffolded for future integration (detects nesting depth at split points)
  • Not yet wired into the chunker loop - list continuation across chunks is complex and left as a follow-up

Testing

  • 12 new tests added to chunk.test.ts
  • Tested locally on Discord with messages that force chunk splits across tables, lists, and inline spans
  • Tables confirmed to stay atomic across chunk boundaries in live Discord rendering

Related issues

#31679 #24363 #32743 #30962

Changed files

  • extensions/discord/src/chunk.ts (modified, +68/-1)
  • extensions/discord/src/monitor/message-handler.process.ts (modified, +1/-0)
  • extensions/discord/src/monitor/reply-delivery.ts (modified, +1/-1)
  • extensions/discord/src/send.outbound.ts (modified, +1/-1)
  • src/auto-reply/chunk.test.ts (modified, +106/-0)
  • src/auto-reply/chunk.ts (modified, +97/-7)
  • src/markdown/blockquotes.ts (added, +85/-0)
  • src/markdown/inline-formatting.ts (added, +90/-0)
  • src/markdown/lists.ts (added, +69/-0)
  • src/markdown/table-spans.ts (added, +99/-0)
  • src/markdown/tables.ts (modified, +6/-2)

PR #63460: fix: preserve markdown formatting across Discord chunk boundaries

Description (problem / solution / changelog)

Fixes #63409. Related: #31679 #24363 #32743 #30962

Problem

When OpenClaw delivers long messages to Discord, the chunking pipeline splits text at 2000-character boundaries. Each chunk renders independently, so formatting that spans a chunk boundary breaks: tables get split mid-row, blockquotes lose their > prefix in continuation chunks, and inline formatting can get orphaned across splits.

Additionally, convertMarkdownTables re-renders the entire message through the IR pipeline when a table is present, and was hardcoding blockquotePrefix: "" - stripping all blockquote markers even in single-chunk messages containing both a table and a blockquote.

Solution

Core chunker (src/auto-reply/chunk.ts)

Integrates table span parsing, blockquote span tracking, and inline marker balancing into chunkMarkdownText, following the existing fence-span pattern.

New span parsers

  • src/markdown/table-spans.ts: parseTableSpans() detects table blocks, skipping content inside fenced code blocks. Tables are atomic; the chunker avoids splitting inside them and repeats the header in continuation chunks. isTableRow requires | at both ends to avoid false positives.
  • src/markdown/blockquotes.ts: parseBlockquoteSpans() detects >-prefixed regions. reapplyBlockquotePrefix() adds > to continuation chunks, bounded to the span end so following plain prose is not incorrectly quoted.
  • src/markdown/inline-formatting.ts: scanUnmatchedInlineMarkers() finds unmatched **, *, backtick at chunk boundaries and closes/reopens them across the split. _ markers apply a word-boundary check to avoid mangling snake_case identifiers.
  • src/markdown/lists.ts: detectListContext() scaffolded for future integration.

Discord-specific chunker (extensions/discord/src/chunk.ts)

The Discord extension has its own line-by-line chunker that bypasses the core chunker. This adds blockquote prefix reapplication and table header repetition directly to chunkDiscordText. Blockquote prefix is only applied after flush(), not on intra-line segment continuations.

Blockquote + table coexistence (src/markdown/tables.ts)

convertMarkdownTables now accepts an optional blockquotePrefix parameter (default "" for backward compat). All three Discord call sites pass "> " so blockquotes survive the IR re-render.

Testing

  • 12 new tests in src/auto-reply/chunk.test.ts
  • Verified live on Discord with messages forcing splits across tables, blockquotes, and inline spans
  • Confirmed blockquotes render correctly in messages containing both tables and blockquotes
  • Confirmed snake_case identifiers are not corrupted at chunk boundaries

Changed files

  • extensions/discord/src/chunk.ts (modified, +82/-2)
  • extensions/discord/src/monitor/message-handler.process.ts (modified, +1/-0)
  • extensions/discord/src/monitor/reply-delivery.ts (modified, +1/-1)
  • extensions/discord/src/send.outbound.ts (modified, +1/-1)
  • src/auto-reply/chunk.test.ts (modified, +106/-0)
  • src/auto-reply/chunk.ts (modified, +97/-7)
  • src/markdown/blockquotes.ts (added, +85/-0)
  • src/markdown/inline-formatting.ts (added, +90/-0)
  • src/markdown/lists.ts (added, +69/-0)
  • src/markdown/table-spans.ts (added, +99/-0)
  • src/markdown/tables.ts (modified, +6/-2)
RAW_BUFFERClick to expand / collapse

Summary

Discord message delivery frequently corrupts markdown formatting by splitting chunks at boundaries that land inside structured elements (blockquotes, nested lists, tables, inline code spans). Each chunk renders independently in Discord, so formatting that spans a chunk boundary breaks visually.

This is distinct from existing fragmentation issues (#31679, #24363) which focus on mid-word splits with specific models. This issue affects all models and manifests as structural formatting corruption rather than simple text fragmentation.

Observed symptoms

  1. Blockquotes break after the first line. A multi-line > blockquote gets split so the first line renders as a quote but continuation lines render as normal text outside the quote block.

  2. Nested bullet lists lose nesting. A sub-bullet that should be indented under its parent gets ejected to the top level when a chunk boundary lands between sibling sub-bullets.

  3. Tables render as raw pipe text. Markdown tables that render correctly in the OpenClaw dashboard arrive in Discord as raw |-delimited text, especially when they span a chunk boundary or follow other content in the same message.

  4. Inline code spans break across chunks. A backtick-delimited code span that starts in one chunk and ends in the next renders with broken formatting in both fragments.

  5. Code blocks split mid-block. A fenced code block gets divided across chunks, so the opening fence is in one message and the closing fence in another, causing both halves to render incorrectly.

Expected behavior

Chunks should never split inside an open formatting context. The chunker should be structure-aware and respect markdown block boundaries (code fences, blockquotes, tables, list nesting levels) when deciding where to split.

Environment

  • OpenClaw version: 2026.4.5
  • Channel: Discord
  • Provider: github-copilot/claude-opus-4.6 (but affects all providers)
  • OS: Linux 6.6.87.2-microsoft-standard-WSL2 (x64)
  • Streaming: default config (not explicitly set to off)

Additional context

The OpenClaw dashboard renders the same responses correctly, confirming the content itself is well-formed markdown. The corruption is introduced by the Discord outbound delivery pipeline during chunking.

Related issues: #31679, #24363, #32743, #30962

extent analysis

TL;DR

Modify the chunking logic in the Discord outbound delivery pipeline to respect markdown block boundaries and prevent splitting inside structured elements.

Guidance

  • Review the existing fragmentation issues (#31679, #24363) to understand how similar problems were addressed, and consider applying similar solutions to this issue.
  • Investigate the chunking algorithm used in the Discord outbound delivery pipeline to identify why it is not respecting markdown block boundaries.
  • Consider implementing a structure-aware chunker that can detect and respect the boundaries of markdown elements such as blockquotes, tables, and code blocks.
  • Test the modified chunking logic with a variety of markdown inputs to ensure it correctly handles different formatting scenarios.

Example

No specific code example can be provided without more information about the chunking algorithm and its implementation.

Notes

The solution may require significant changes to the chunking logic and may involve coordinating with the Discord API team to ensure compatibility.

Recommendation

Apply a workaround by modifying the chunking logic to respect markdown block boundaries, as this is a more targeted solution than upgrading to a potentially non-existent fixed version.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

FAQ

Expected behavior

Chunks should never split inside an open formatting context. The chunker should be structure-aware and respect markdown block boundaries (code fences, blockquotes, tables, list nesting levels) when deciding where to split.

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING