openclaw - 💡(How to fix) Fix emotion-tags: line-start `[label1][label2]` ambiguity between emotion-pair and markdown reference link [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#72821Fetched 2026-04-28 06:31:57
View on GitHub
Comments
0
Participants
1
Timeline
0
Reactions
0
Participants

isSecondLabelInMarkdownReferenceLink() and isFollowedByMarkdownReferenceLink() in src/shared/text/emotion-tags.ts gate reference-link detection on hasNonWhitespaceBeforeOnLine. At line start, [fast][1] is mis-classified as adjacent emotion tags and stripped to [1]. Reported by Copilot on PRs #72229 and #72266.

The simple suggested fix (drop the hasNonWhitespaceBeforeOnLine guard) breaks two existing tests in src/shared/text/emotion-tags.test.ts:

  • [warmly][softly] hello there → expected to strip both as adjacent emotion tags
  • [fast][softly] go now. → expected to strip both as adjacent emotion tags

Root Cause

isSecondLabelInMarkdownReferenceLink() and isFollowedByMarkdownReferenceLink() in src/shared/text/emotion-tags.ts gate reference-link detection on hasNonWhitespaceBeforeOnLine. At line start, [fast][1] is mis-classified as adjacent emotion tags and stripped to [1]. Reported by Copilot on PRs #72229 and #72266.

The simple suggested fix (drop the hasNonWhitespaceBeforeOnLine guard) breaks two existing tests in src/shared/text/emotion-tags.test.ts:

  • [warmly][softly] hello there → expected to strip both as adjacent emotion tags
  • [fast][softly] go now. → expected to strip both as adjacent emotion tags

Code Example

const allowlistedNamedReference = stripEmotionTags("See [fast][clear] before choosing.");
expect(allowlistedNamedReference).toEqual({
  text: "See [fast][clear] before choosing.",
  changed: false,
});
RAW_BUFFERClick to expand / collapse

Summary

isSecondLabelInMarkdownReferenceLink() and isFollowedByMarkdownReferenceLink() in src/shared/text/emotion-tags.ts gate reference-link detection on hasNonWhitespaceBeforeOnLine. At line start, [fast][1] is mis-classified as adjacent emotion tags and stripped to [1]. Reported by Copilot on PRs #72229 and #72266.

The simple suggested fix (drop the hasNonWhitespaceBeforeOnLine guard) breaks two existing tests in src/shared/text/emotion-tags.test.ts:

  • [warmly][softly] hello there → expected to strip both as adjacent emotion tags
  • [fast][softly] go now. → expected to strip both as adjacent emotion tags

Tried-and-rejected heuristic

Drop the guard, but only count the pair as a reference link if the SECOND label is NOT in EMOTION_TAG_WORDS.

This handles [fast][1] ✓, [clear][docs] ✓, [warmly][softly] ✓, [fast][softly] ✓ — but breaks the existing test on line 57:

const allowlistedNamedReference = stripEmotionTags("See [fast][clear] before choosing.");
expect(allowlistedNamedReference).toEqual({
  text: "See [fast][clear] before choosing.",
  changed: false,
});

[fast][clear] is preserved here as a reference link even though clear is in EMOTION_TAG_WORDS. The test treats reference-link semantics as winning when there's leading non-whitespace; the heuristic above can't tell [fast][clear] (reference) apart from [fast][clear] (emotion pair) from labels alone.

What a proper fix needs

A label-content-only heuristic isn't sufficient. A correct fix needs document-level context, e.g.:

  • Detect a corresponding [clear]: <url> reference definition elsewhere in the input. If present, the bracket-pair is unambiguously a markdown reference link.
  • Or product input: clarify whether [emotion-word][emotion-word] at line start should always strip as emotion tags (current behavior), or whether reference-link semantics should win.

Suggested next steps:

  1. Decide the desired behavior for [emotion-word][emotion-word] at line start when no reference definition exists in the document — strip-as-emotion (current) or preserve-as-reference (Copilot's preferred).
  2. If preserving, parse the input for ^\[([^\]\n]+)\]:\s definitions and gate reference-link classification on a definition existing for the second label.
  3. Add bidirectional test coverage: line-start emotion-pair stays stripped; line-start [fast][1] (no definition) preserves; [fast][clear] with [clear]: … definition preserves; [fast][clear] without definition strips.

Scope of impact

Any chat-history or live-stream text that uses markdown reference-link syntax at the start of a line is at risk. The narrow practical impact today is the [fast][1] example surviving as [1] in off/on modes — unlikely to corrupt critical content, but visibly wrong on any docs/markdown-rich assistant output.

Discovered

PR review on #72229 / #72266. Inline comment placed at src/shared/text/emotion-tags.ts line 211-220 in commit f59cde0a6f documenting the ambiguity. Threads on both PRs left open with a pointer to this issue.

extent analysis

TL;DR

The issue can be resolved by implementing a document-level context check to distinguish between markdown reference links and adjacent emotion tags.

Guidance

  • Decide on the desired behavior for [emotion-word][emotion-word] at line start when no reference definition exists in the document.
  • Parse the input for reference definitions and gate reference-link classification on a definition existing for the second label.
  • Add test coverage for different scenarios, including line-start emotion-pairs, [fast][1], and [fast][clear] with and without definitions.
  • Consider the scope of impact on chat-history or live-stream text that uses markdown reference-link syntax at the start of a line.

Example

No code snippet is provided as the issue requires a more complex solution involving document-level context and reference definition parsing.

Notes

The issue is specific to the emotion-tags.ts file and requires a careful consideration of the desired behavior for different scenarios. The suggested fix needs to balance the requirements of preserving reference links and stripping adjacent emotion tags.

Recommendation

Apply a workaround by implementing a document-level context check to distinguish between markdown reference links and adjacent emotion tags, as this approach addresses the root cause of the issue and provides a more robust solution.

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 emotion-tags: line-start `[label1][label2]` ambiguity between emotion-pair and markdown reference link [1 participants]