[MODEL BEHAVIOR] Claude doesn't use longer fence sequences when generating nested markdown code blocks
Behavior Type
Other unexpected behavior
Claude Opus 4.5 and other models struggle with nested markdown codeblocks (backticks), and variety of markdown syntax (and different parsing also depending with there is type after opening backticks or not, like in case of this github issues...) , even this issue bug report co-generated with Claude code had to be manually edited and improved to render correctly on github...
What You Asked Claude to Do
Asked Claude to generate markdown documentation that demonstrates how to write code blocks (e.g., a tutorial, README showing examples, or any meta-documentation about markdown syntax).
Example prompt:
"Write a markdown guide showing how to create fenced code blocks with syntax highlighting"
Or when Claude naturally generates documentation that includes code examples containing their own code blocks.
What Claude Actually Did
Claude generates markdown using the same fence length ( ` ) at all nesting levels, which breaks the markdown structure. For example:
Here's how to write a code block:
print("hello")
The above shows a Python code block.
When the outer block also uses ` , the parser terminates at the first inner ` instead of the intended closing fence.
What Should Have Happened
Claude should recognize nested code block scenarios and use progressively longer fence sequences per CommonMark §4.5:
`````markdown
Here's how to write a code block:
print("hello")
The above shows a Python code block.
`````
The outer fence (5 backticks) properly contains the inner fence (3 backticks) because the closing fence must be at least as long as the opening fence.
For deeper nesting (e.g., documentation about documentation):
``````markdown
How to document code examples
Use longer fences to wrap examples:
`````markdown
Here's a code block:
print("hello")
`````
``````
Files Affected
Any markdown file Claude generates that contains nested code block examples, including:
- README files with usage examples
- Tutorials teaching markdown syntax
- Documentation showing code snippets
- Meta-documentation about formatting
Permission Mode
N/A - this is model output behavior
Can You Reproduce This?
Yes, consistently
Reproduction Steps
- Ask Claude: "Write a markdown tutorial showing how to create fenced code blocks"
- Or ask Claude to document a function with example usage that includes code blocks
- Observe that Claude uses
`for both outer documentation blocks and inner example blocks - The resulting markdown is malformed - parsers close at the first
`encountered
Claude Model
Opus 4.5 (default) - but likely affects all models
Claude Code Version
2.1.4
Platform
Anthropic API
Conversation Log
Example of broken output Claude generates:
Here is how to format code:
def hello():
print("world")
This creates a syntax-highlighted block.
The second ` closes the outer block prematurely.
Impact Level
Medium - Creates difficulty using a feature
Additional Context
CommonMark Spec Reference
Per CommonMark §4.5:
A code fence is a sequence of at least three consecutive backtick characters (``) or tilde characters (~`).
The closing code fence must be at least as long as the opening fence.
This means:
- `
```(5) can contain`` (3) - `
````(6) can contain``(4) can contain`` (3)
Why This Matters
Claude is often used to:
- Generate documentation
- Write tutorials and guides
- Create README files
- Produce technical content
When this content needs to show markdown examples (very common!), Claude's output is broken and requires manual fixing.
Suggested Fix (Option A: Model-side)
When Claude detects it needs to output a code block that will contain other code blocks, it should:
- Count the maximum fence depth needed
- Use appropriately longer fences for outer blocks
- Example: If showing a
`example, wrap it in ```or````
Alternative Solution (Option B: Post-processing)
An alternative approach: Claude could output XML-style semantic markup for code blocks that can nest naturally, and downstream libraries/tools would convert to proper markdown:
Claude outputs:
<markdown-codeblock lang="markdown">
Here's how to write a code block:
<markdown-codeblock lang="python">
print("hello")
</markdown-codeblock>
The above shows a Python code block.
</markdown-codeblock>
Post-processor converts to:
`````markdown
Here's how to write a code block:
print("hello")
The above shows a Python code block.
`````
Pros:
- Nesting is unambiguous (XML handles it natively)
- Post-processor can calculate optimal fence lengths
- Could be extended with additional metadata
Cons:
- Requires all consumers to implement post-processing
- Raw output is not directly usable as markdown
- Additional complexity in toolchain
- Breaking change for existing integrations
This could be opt-in via a parameter or output format setting, preserving backward compatibility.
Related Issues
- #12655 - Code block italicization (different rendering bug)
- #17554 - Missing blank lines in generated markdown (different generation bug)
- #14238 - Italicization in code samples (different bug)
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗