openclaw - 💡(How to fix) Fix [Bug] Matrix: formatted_body missing when message is plain text with @mentions

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…

When OpenClaw sends a Matrix message that contains @user:server mentions but no other markdown formatting (no bold, lists, etc.), the message is sent with m.mentions metadata but without formatted_body and format fields.

This means the @mentions are detected for notification purposes (notifications work ✅), but the Matrix HTML link (<a href="https://matrix.to/#/@user:server">@user:server</a>) is never generated, so the mention appears as plain text in Element and other clients that rely on formatted_body for rendering.

Root Cause

In send-COLF00ag.js, the enrichMatrixFormattedContent function:

  1. Renders markdown to HTML (which includes converting @user:server to <a> links via resolveMarkdownMentionState)
  2. If the resulting HTML is empty/falsy, it deletes both format and formatted_body

The issue is that when the markdown renderer produces simple HTML (just <p> tags wrapping text), and the @mentions have been masked during parsing, the rendered HTML may evaluate as falsy — even though it contains the critical mention links.

The resolveMarkdownMentionState function masks @mentions before markdown parsing (via maskEscapedMentions) and restores them afterward (restoreEscapedMentionsInBlockTokens). If the masking/restoration doesn't properly produce <a> links in the final HTML for simple plain-text messages, the m.mentions metadata is populated correctly but the visual links are lost.

Code Example

@alice:server @bob:server — Status check on the project.

---

{
  "msgtype": "m.text",
  "body": "@alice:server @bob:server — Status check on the project.",
  "m.mentions": { "user_ids": ["@alice:server", "@bob:server"] }
}

---

@alice:server @bob:server — **Status check** on the project.

---

{
  "msgtype": "m.text",
  "body": "@alice:server @bob:server — **Status check** on the project.",
  "format": "org.matrix.custom.html",
  "formatted_body": "<p><a href=\"https://matrix.to/#/@alice:server\">@alice:server</a> <a href=\"https://matrix.to/#/@bob:server\">@bob:server</a> — <strong>Status check</strong>...</p>",
  "m.mentions": { "user_ids": ["@alice:server", "@bob:server"] }
}

---

if (!html) {
    delete params.content.format;
    delete params.content.formatted_body;
    return;
}
RAW_BUFFERClick to expand / collapse

GitHub Issue: Matrix messages missing formatted_body when body is plain text with @mentions

Labels: bug, matrix

Description

When OpenClaw sends a Matrix message that contains @user:server mentions but no other markdown formatting (no bold, lists, etc.), the message is sent with m.mentions metadata but without formatted_body and format fields.

This means the @mentions are detected for notification purposes (notifications work ✅), but the Matrix HTML link (<a href="https://matrix.to/#/@user:server">@user:server</a>) is never generated, so the mention appears as plain text in Element and other clients that rely on formatted_body for rendering.

Expected Behavior

Messages with @user:server patterns should always include formatted_body with clickable HTML links, because enrichMatrixFormattedContent should render the mention links into the HTML even when the rest of the message is plain text.

Actual Behavior

When the markdown renderer produces HTML that is "not different enough" from the plain text body (i.e., just <p>text</p>), enrichMatrixFormattedContent deletes format and formatted_body entirely — including the mention links that would have been in the HTML.

Example

Plain text message (BUG):

@alice:server @bob:server — Status check on the project.

Result:

{
  "msgtype": "m.text",
  "body": "@alice:server @bob:server — Status check on the project.",
  "m.mentions": { "user_ids": ["@alice:server", "@bob:server"] }
}

Missing: format and formatted_body fields.

Same message with markdown (WORKS):

@alice:server @bob:server — **Status check** on the project.

Result:

{
  "msgtype": "m.text",
  "body": "@alice:server @bob:server — **Status check** on the project.",
  "format": "org.matrix.custom.html",
  "formatted_body": "<p><a href=\"https://matrix.to/#/@alice:server\">@alice:server</a> <a href=\"https://matrix.to/#/@bob:server\">@bob:server</a> — <strong>Status check</strong>...</p>",
  "m.mentions": { "user_ids": ["@alice:server", "@bob:server"] }
}

Root Cause

In send-COLF00ag.js, the enrichMatrixFormattedContent function:

  1. Renders markdown to HTML (which includes converting @user:server to <a> links via resolveMarkdownMentionState)
  2. If the resulting HTML is empty/falsy, it deletes both format and formatted_body

The issue is that when the markdown renderer produces simple HTML (just <p> tags wrapping text), and the @mentions have been masked during parsing, the rendered HTML may evaluate as falsy — even though it contains the critical mention links.

The resolveMarkdownMentionState function masks @mentions before markdown parsing (via maskEscapedMentions) and restores them afterward (restoreEscapedMentionsInBlockTokens). If the masking/restoration doesn't properly produce <a> links in the final HTML for simple plain-text messages, the m.mentions metadata is populated correctly but the visual links are lost.

Suggested Fix

enrichMatrixFormattedContent should preserve formatted_body whenever m.mentions contains user_ids, regardless of whether the rest of the HTML is "simple." Mention links are functional content, not decorative, and clients that render formatted_body will not display clickable links without them.

Specifically, the check at line ~585:

if (!html) {
    delete params.content.format;
    delete params.content.formatted_body;
    return;
}

Should also consider whether mentions.user_ids is non-empty — if there are mention user IDs, the HTML should still be emitted even if it's "simple," because it contains <a> links that aren't in the plain text body.

Environment

  • OpenClaw: v2026.5.12
  • Matrix plugin: @openclaw/matrix (bundled)
  • Homeserver: Synapse (local, v1.x)

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…

Still need to ship something?

×6

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

Back to top recommendations

TRENDING

openclaw - 💡(How to fix) Fix [Bug] Matrix: formatted_body missing when message is plain text with @mentions