Skip to content

fix(media): gate markdown image extraction by channel#72718

Merged
steipete merged 1 commit intoopenclaw:mainfrom
Bartok9:fix/72642-discord-markdown-badge-extraction
Apr 27, 2026
Merged

fix(media): gate markdown image extraction by channel#72718
steipete merged 1 commit intoopenclaw:mainfrom
Bartok9:fix/72642-discord-markdown-badge-extraction

Conversation

@Bartok9
Copy link
Copy Markdown
Contributor

@Bartok9 Bartok9 commented Apr 27, 2026

Problem

Discord final replies can contain incidental Markdown images from README snippets, package summaries, or badge examples. Since #66471, the shared media parser lifted remote Markdown image syntax into mediaUrls, so Discord delivered those incidental images as file attachments.

Example:

tech: ![Node.js](https://img.shields.io/badge/Node.js-339933?logo=node.js&logoColor=white)

That should remain visible reply text on Discord, not become an attachment.

Fix

Make Markdown-image media extraction opt-in:

  • splitMediaFromOutput() keeps Markdown images as text by default.
  • Outbound payload planning can enable extraction via channel context.
  • ChannelOutboundAdapter.extractMarkdownImages is the generic channel-owned capability.
  • Telegram opts in, preserving the behavior added for Telegram media replies.
  • Explicit MEDIA: directives remain unchanged, so agents and trusted tools can still intentionally attach any valid public media URL.

Tests

  • src/media/parse.test.ts
  • src/infra/outbound/payloads.test.ts
  • src/infra/outbound/deliver.test.ts
  • src/auto-reply/reply/agent-runner-payloads.test.ts
  • pnpm check:changed

Closes #72642.

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Apr 27, 2026

Greptile Summary

This PR adds an isBadgeUrl() filter to isRemoteMarkdownImageMedia() so that well-known badge/shield images embedded in markdown (shields.io, badgen.net, GitHub CI badge.svg, etc.) are no longer extracted as Discord file attachments. Explicit MEDIA: tokens are deliberately unaffected.

Confidence Score: 4/5

Safe to merge; fix is narrowly scoped and well-tested with only a minor regex style issue.

Only P2 finding present: a dead \? branch in BADGE_PATH_PATTERN_RE that has no effect on runtime behaviour because the regex is always tested against URL.pathname. Logic, tests, and the overall design are sound.

No files require special attention.

Prompt To Fix All With AI
This is a comment left during a code review.
Path: src/media/parse.ts
Line: 259

Comment:
**Dead `\?` branch in `BADGE_PATH_PATTERN_RE`**

The regex is always tested against `parsed.pathname`, but `URL.pathname` never contains a `?` — query parameters live in `URL.search`. The `\?` alternative in `(?:\?|$)` is therefore unreachable dead code in both positions. The existing `$` anchor already covers the end-of-path case correctly (e.g. `https://github.com/owner/repo/badge.svg?v=1` produces pathname `/owner/repo/badge.svg`, matched by `$`).

```suggestion
const BADGE_PATH_PATTERN_RE = /\/badge\.svg$|\/workflows\/[^/]+\/badge(?:\.|$)/i;
```

How can I resolve this? If you propose a fix, please make it concise.

Reviews (1): Last reviewed commit: "fix: exclude badge/shield URLs from mark..." | Re-trigger Greptile

Comment thread src/media/parse.ts Outdated

// Matches badge paths on generic hosts (e.g. GitHub CI status badges:
// https://github.com/owner/repo/actions/workflows/ci.yml/badge.svg).
const BADGE_PATH_PATTERN_RE = /\/badge\.svg(?:\?|$)|\/workflows\/[^/]+\/badge(?:\.|$)/i;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Dead \? branch in BADGE_PATH_PATTERN_RE

The regex is always tested against parsed.pathname, but URL.pathname never contains a ? — query parameters live in URL.search. The \? alternative in (?:\?|$) is therefore unreachable dead code in both positions. The existing $ anchor already covers the end-of-path case correctly (e.g. https://github.com/owner/repo/badge.svg?v=1 produces pathname /owner/repo/badge.svg, matched by $).

Suggested change
const BADGE_PATH_PATTERN_RE = /\/badge\.svg(?:\?|$)|\/workflows\/[^/]+\/badge(?:\.|$)/i;
const BADGE_PATH_PATTERN_RE = /\/badge\.svg$|\/workflows\/[^/]+\/badge(?:\.|$)/i;
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/media/parse.ts
Line: 259

Comment:
**Dead `\?` branch in `BADGE_PATH_PATTERN_RE`**

The regex is always tested against `parsed.pathname`, but `URL.pathname` never contains a `?` — query parameters live in `URL.search`. The `\?` alternative in `(?:\?|$)` is therefore unreachable dead code in both positions. The existing `$` anchor already covers the end-of-path case correctly (e.g. `https://github.com/owner/repo/badge.svg?v=1` produces pathname `/owner/repo/badge.svg`, matched by `$`).

```suggestion
const BADGE_PATH_PATTERN_RE = /\/badge\.svg$|\/workflows\/[^/]+\/badge(?:\.|$)/i;
```

How can I resolve this? If you propose a fix, please make it concise.

@steipete steipete force-pushed the fix/72642-discord-markdown-badge-extraction branch from a98e8bb to e522084 Compare April 27, 2026 10:17
@openclaw-barnacle openclaw-barnacle Bot added docs Improvements or additions to documentation channel: telegram Channel integration: telegram labels Apr 27, 2026
@steipete steipete changed the title fix: exclude badge/shield URLs from markdown-image media extraction fix(media): gate markdown image extraction by channel Apr 27, 2026
Closes openclaw#72642

Co-authored-by: Bartok9 <danielrpike9@gmail.com>
@steipete steipete force-pushed the fix/72642-discord-markdown-badge-extraction branch from e522084 to 7cbc9a8 Compare April 27, 2026 10:27
@steipete steipete merged commit f0b327c into openclaw:main Apr 27, 2026
10 of 11 checks passed
@steipete
Copy link
Copy Markdown
Contributor

Landed cleanly after rewriting this to a channel-owned opt-in instead of a badge-host blacklist.

  • Source commit: 7cbc9a8
  • Merge commit: f0b327c
  • Gate: Blacksmith Testbox focused regression tests for media/outbound/auto-reply passed, then pnpm check:changed passed on a fresh current-main Testbox.

Thanks @Bartok9!

ogt-redknie pushed a commit to ogt-redknie/OPENX that referenced this pull request May 2, 2026
Closes openclaw#72642

Co-authored-by: Peter Steinberger <steipete@gmail.com>
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request May 9, 2026
Closes openclaw#72642

Co-authored-by: Peter Steinberger <steipete@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

channel: telegram Channel integration: telegram docs Improvements or additions to documentation size: M

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Discord final replies attach Markdown image badges from assistant text

2 participants