#20795: fix(markdown): prevent triple newlines after blockquotes
size: XS
Cluster:
Model Reasoning Fixes
## Summary
Describe the problem and fix in 2–5 bullets:
- Problem: Blockquotes produce triple newlines (`\n\n\n`) instead of double newlines (`\n\n`) when followed by other content
- Why it matters: Causes excessive spacing in rendered output across messaging channels
- What changed: Added `blockquoteDepth` tracking to `RenderEnv`, normalize trailing newlines when exiting outermost blockquote
- What did NOT change (scope boundary): All other markdown rendering behavior unchanged
## Change Type (select all)
- [x] Bug fix
- [ ] Feature
- [ ] Refactor
- [ ] Docs
- [ ] Security hardening
- [ ] Chore/infra
## Scope (select all touched areas)
- [x] Gateway / orchestration
- [ ] Skills / tool execution
- [ ] Auth / tokens
- [ ] Memory / storage
- [ ] Integrations
- [ ] API / contracts
- [ ] UI / DX
- [ ] CI/CD / infra
## Linked Issue/PR
- Closes # N/A
- Related # Bug documented in `src/markdown/ir.blockquote-spacing.test.ts`
## User-visible / Behavior Changes
Blockquote followed by paragraph now correctly renders with one blank line (double newline) instead of two blank lines (triple newline).
## Security Impact (required)
- New permissions/capabilities? `No`
- Secrets/tokens handling changed? `No`
- New/changed network calls? `No`
- Command/tool execution surface changed? `No`
- Data access scope changed? `No`
- If any `Yes`, explain risk + mitigation: N/A
## Repro + Verification
### Environment
- OS: Any
- Runtime/container: Node.js 22+
- Model/provider: N/A
- Integration/channel (if any): All messaging channels
- Relevant config (redacted): N/A
### Steps
1. Run `pnpm test src/markdown/ir.blockquote-spacing.test.ts`
2. Verify all blockquote spacing tests pass
3. Run `pnpm build && pnpm check`
### Expected
- All tests in `ir.blockquote-spacing.test.ts` pass
- No triple newlines (`\n\n\n`) in output
### Actual
- (To be verified by CI)
## Evidence
Attach at least one:
- [x] Failing test/log before + passing after (existing test file documents expected behavior)
- [ ] Trace/log snippets
- [ ] Screenshot/recording
- [ ] Perf numbers (if relevant)
## Human Verification (required)
What you personally verified (not just CI), and how:
- Verified scenarios: Code review of blockquote_open/blockquote_close handlers, traced newline accumulation logic
- Edge cases checked: Nested blockquotes (only normalizes on outermost close), consecutive blockquotes
- What you did **not** verify: Local test execution (no pnpm environment)
## Compatibility / Migration
- Backward compatible? `Yes`
- Config/env changes? `No`
- Migration needed? `No`
- If yes, exact upgrade steps: N/A
## Failure Recovery (if this breaks)
- How to disable/revert this change quickly: Revert commit
- Files/config to restore: `src/markdown/ir.ts`
- Known bad symptoms reviewers should watch for: Incorrect spacing in markdown rendering, missing newlines between blocks
## Risks and Mitigations
- Risk: Over-normalization could remove intentional newlines in edge cases
- Mitigation: Only normalizes triple→double newlines, only on outermost blockquote close, preserves correct double-newline spacing
---
Addresses bug documented in `src/markdown/ir.blockquote-spacing.test.ts`.
<!-- greptile_comment -->
<h3>Greptile Summary</h3>
Added `blockquoteDepth` tracking to fix triple newline bug after blockquotes. The fix normalizes `\n\n\n` to `\n\n` when exiting outermost blockquote, ensuring consistent double-newline spacing between block elements. The implementation correctly handles nested blockquotes by only normalizing at the outermost level, and the while loop properly reduces any number of excess newlines down to the standard double-newline separator.
<h3>Confidence Score: 5/5</h3>
- This PR is safe to merge - it's a focused bug fix with comprehensive test coverage
- The fix is minimal, well-scoped, and addresses a clearly documented bug. The implementation correctly handles edge cases (nested blockquotes, various block elements), and comprehensive tests verify the behavior. The normalization logic is sound and won't affect other markdown rendering.
- No files require special attention
<sub>Last reviewed commit: 0a25cc7</sub>
<!-- greptile_other_comments_section -->
<sub>(3/5) Reply to the agent's comments like "Can you suggest a fix for this @greptileai?" or ask follow-up questions!</sub>
<!-- /greptile_comment -->
Most Similar PRs
#16733: fix(ui): avoid injected newlines when tool output is hidden
by jp117 · 2026-02-15
77.8%
#4249: fix(telegram): properly nest link tags inside bold/italic formatting
by pradeeppeddineni · 2026-01-29
77.8%
#10612: fix: trim leading blank lines on first emitted chunk only (#5530)
by 1kuna · 2026-02-06
77.7%
#2716: Fix #2678: markdown horizontal rules not rendering in web chat
by Ambar-13 · 2026-01-27
77.6%
#18655: fix(mattermost): preserve markdown formatting and native tables
by echo931 · 2026-02-16
74.2%
#15204: fix(ui): preserve angle-bracketed text in chat
by bufordtjustice2918 · 2026-02-13
74.1%
#5080: fix(reply): fix duplicate block replies by unblocking coalesced pay...
by yassine20011 · 2026-01-31
73.8%
#11048: fix: address repository issues (env, author, CI comments, security ...
by cavula · 2026-02-07
73.5%
#20419: fix(webchat): explicitly pass gfm and breaks options to marked.parse()
by Limitless2023 · 2026-02-18
73.4%
#12180: fix: merge multi-block assistant texts into single reply
by 1960697431 · 2026-02-08
73.4%