#20419: fix(webchat): explicitly pass gfm and breaks options to marked.parse()
app: web-ui
size: XS
## Problem
Markdown tables in Gateway WebChat render as raw pipe-separated text inside a `<p>` tag:
```html
<!-- Actual (broken) -->
<p>Text before. | Col1 | Col2 | |------|------| | A | B | Text after.</p>
<!-- Expected -->
<table><thead><tr><th>Col1</th><th>Col2</th>...</table>
```
## Root Cause
In **marked v7+**, passing _any_ options object to `marked.parse()` creates an **isolated options context** that does **not** inherit values set via `marked.setOptions()`. This means:
```ts
marked.setOptions({ gfm: true, breaks: true }); // ← set globally
// Later — the { renderer } argument creates an isolated context:
marked.parse(text, { renderer: htmlEscapeRenderer }); // ← gfm silently resets to false!
```
When `gfm: false`, the GFM table extension is not loaded and table syntax passes through unparsed as inline text.
**Reproducer:**
```ts
marked.parse('| a | b |\n|---|---|\n| 1 | 2 |', { gfm: false })
// → '<p>| a | b |\n|---|---|\n| 1 | 2 |</p>' ✗
marked.parse('| a | b |\n|---|---|\n| 1 | 2 |', { gfm: true })
// → '<table>...</table>' ✓
```
## Fix
Forward `gfm: true` and `breaks: true` explicitly in the `marked.parse()` call alongside the renderer so the options are always applied regardless of marked version behaviour.
This also affects other GFM extensions: strikethrough, autolinks, task list items.
Fixes #20410
<!-- greptile_comment -->
<h3>Greptile Summary</h3>
Fixes GFM markdown table rendering (and other GFM extensions like strikethrough, autolinks, task lists) in Gateway WebChat by explicitly passing `gfm: true` and `breaks: true` in the `marked.parse()` call in `ui/src/ui/markdown.ts`.
- In `marked` v7+ (project uses `^17.0.3`), passing any options object to `marked.parse()` creates an isolated options context that does **not** inherit values from `marked.setOptions()`. The existing code passed `{ renderer: htmlEscapeRenderer }`, which silently reset `gfm` to `false`, causing tables to render as raw pipe-separated text.
- The fix correctly forwards `gfm: true` and `breaks: true` alongside the renderer so the options are always applied.
- The existing `marked.setOptions()` call is preserved for any un-parameterized `marked.parse()` calls elsewhere (e.g., `src/auto-reply/reply/export-html/template.js:1726`).
- No test was added for the specific table rendering regression; a test like `expect(toSanitizedMarkdownHtml('| a | b |\n|---|---|\n| 1 | 2 |')).toContain('<table>')` would help prevent future regressions.
<h3>Confidence Score: 5/5</h3>
- This PR is safe to merge with minimal risk — it's a targeted, well-understood bug fix.
- The change is small (2 added option properties + explanatory comments), correctly addresses a documented behavior change in marked v7+, and doesn't alter any logic or introduce new code paths. The project uses marked ^17.0.3, confirming the isolated options context behavior. No other marked.parse() calls with options objects exist in the codebase.
- No files require special attention.
<sub>Last reviewed commit: 063f52d</sub>
<!-- greptile_other_comments_section -->
<!-- /greptile_comment -->
Most Similar PRs
#20423: fix(web-fetch): cap htmlToMarkdown input size to prevent catastroph...
by Limitless2023 · 2026-02-18
79.0%
#20441: fix: preserve newlines for markdown table rendering in WebChat
by MisterGuy420 · 2026-02-18
78.2%
#2716: Fix #2678: markdown horizontal rules not rendering in web chat
by Ambar-13 · 2026-01-27
77.4%
#4249: fix(telegram): properly nest link tags inside bold/italic formatting
by pradeeppeddineni · 2026-01-29
76.1%
#15204: fix(ui): preserve angle-bracketed text in chat
by bufordtjustice2918 · 2026-02-13
75.5%
#16733: fix(ui): avoid injected newlines when tool output is hidden
by jp117 · 2026-02-15
74.5%
#12257: fix(mattermost): default table mode to 'off' for native Markdown re...
by mcaxtr · 2026-02-09
74.3%
#18655: fix(mattermost): preserve markdown formatting and native tables
by echo931 · 2026-02-16
74.1%
#14940: fix(googlechat): convert Markdown formatting to Google Chat markup
by brandonwise · 2026-02-12
74.1%
#20795: fix(markdown): prevent triple newlines after blockquotes
by novalis133 · 2026-02-19
73.4%