Diagnosing Markdown Nested Block Rendering Failures
A diagnostic guide for when fenced code blocks, blockquotes, or nested lists disappear or render incorrectly in CommonMark‑compliant parsers. It covers CommonMark, GFM, Pandoc, and markdown‑it, with a symptom‑cause table, ordered checks, fixes, and escalation criteria.
25 Jun 2026, 14:00 UTC

The Problem
You write a list item that contains a fenced code block, push to GitHub, and the code fence renders as literal backticks instead of a <pre><code> block. Or a blockquote inside a list item loses its > prefix and merges into the parent paragraph. These failures stem from indentation and blank‑line rules that differ between CommonMark, GitHub‑Flavored Markdown (GFM), Pandoc, and markdown‑it. The symptom is always the same: nested block elements vanish or render as plain text.
Quick Diagnosis Table
| Symptom | Likely Cause | Parser Context |
|---|---|---|
| Fenced code block in list appears as raw markdown | Insufficient indentation (needs 8 spaces: 4 for list + 4 for code) | CommonMark §5.2, GFM |
Blockquote in list loses > prefix, merges with list text | Missing blank line after list marker before > indent | GFM requires blank line + 4‑space indent |
| List inside blockquote merges into parent paragraph | No blank line after > before list start | CommonMark strict |
| Nested ordered list numbering resets to 1 | Parser treats nested list as separate; GFM continues only if parent ordered and indent matches | GFM extension |
Ordered Checks
- Validate indentation. Each nesting level adds 4 spaces (or 1 tab equivalent). A code fence inside a list item needs 8 spaces before the opening backticks. Run
sed -n l file.md(Linux/macOS) orcat -A file.mdto make spaces visible. - Verify blank lines. CommonMark §5 requires a blank line before and after nested block elements. Check for a blank line after the list marker (
-or1.) before a blockquote or code fence. - Check parser configuration. markdown‑it with
commonmark: truedisables all GFM extensions (tables, task lists, relaxed nesting). For GFM‑like behavior without strict mode, usehtml: true, linkify: true, typographer: true. - Inspect HTML output. Look for missing
<blockquote>,<pre><code>, or incorrect<ul>/<ol>nesting. Pipe throughtidy -q -indentto normalize whitespace before diffing. - Test with reference parsers. Run the same input through:
Compare HTML structure, ignoring whitespace.cmark --to html file.md # CommonMark reference pandoc -f gfm -t html file.md # GFM via Pandoc npx markdown-it --commonmark file.md # markdown‑it strict mode curl -X POST -H "Accept: application/vnd.github+json" \ -d '{"text":"...","mode":"gfm","context":"owner/repo"}' \ https://api.github.com/markdown # GitHub API exact rendering
Fixes Tied to Findings
Code block inside list item
Indent the fence by 8 spaces (4 for list + 4 for code) or use tilde fences with the same indentation. Both satisfy CommonMark §5.2.
- List item
```js
console.log('hello');
```
Blockquote inside list item
Add a blank line after the list marker, then indent > by 4 spaces.
- List item
> Quoted text
> continues here
List inside blockquote
Put a blank line after > then start the list with proper indent.
> Intro paragraph
>
> - Nested item
> - Another
Nested ordered list numbering
GFM continues numbering only when the parent is ordered and indentation matches exactly. If you need a specific start number, emit HTML with <ol start="3"> post‑processing, or accept the parser default.
Escalation Criteria
Escalate when:
- Content loss affects more than 5% of documents in your corpus.
- Rendering differs between production (GitHub) and local preview (VS Code markdown‑it).
- Security‑relevant: malformed nesting allows HTML injection via raw HTML passthrough in unsafe parser configs (e.g.,
html: truewithout sanitization). - CI/CD pipeline fails due to markdownlint rules MD007 (ul‑indent), MD027 (multiple spaces after blockquote), or MD029 (ol‑prefix) that cannot be resolved by style changes alone.
Verification Checklist
- Create a test fixture covering all four nesting patterns. Render with
cmark,pandoc -f gfm,npx markdown-it --commonmark, and GitHub API. Diff HTML structure. - Run
markdownlint-cli v0.35+with rules MD007, MD027, MD029 to catch indentation violations pre‑render. - Add CI integration test: render known‑good fixtures with production parser, diff against golden HTML files (ignore whitespace).
- For GitHub‑specific rendering, use
POST /markdownwithmode: gfmandcontext: <repo>to get exact GFM output including repo‑relative links and mentions. - Pipe parser HTML through DOMPurify with
ALLOWED_TAGS: ['blockquote','pre','code','ul','ol','li','p']and confirm nested structure survives sanitization. - Document minimum parser versions:
cmark 0.30+,Pandoc 2.11+,markdown‑it 12+— compliance improved significantly at these releases.
Limitations
- CommonMark treats a tab as 4‑space equivalent only at tab stop 4. Mixed tabs/spaces cause undefined rendering; enforce spaces‑only in style guides.
- Pandoc’s
markdown_githubformat adds Pandoc‑specific behaviors (implicit header references, fenced code attributes) beyond GFM spec. - GFM spec is not fully aligned with CommonMark 0.31.2; lazy continuation in blockquotes works in GFM but not strict CommonMark.
- Client‑side sanitization (DOMPurify) may strip nested block elements if HTML output is malformed — verify sanitizer config allows proper nesting.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.