#8341·tiptap

[Bug] @tiptap/markdown: code blocks containing backticks serialize with an unsafe fence and break on round trip

Author: timohausmannCreated Sep 15, 2026Updated Sep 16, 2026
Labelsstatus: triagearea: markdowncomplexity: easyimpact: medium

Affected Packages

markdown, extension-code-block

Tiptap Version

3.30.5

Browser Used

Not browser-specific

What happened?

Code blocks are always serialized with exactly three backticks, even when their content contains a triple-backtick fence.

A valid Markdown code block enclosed in four backticks parses correctly. After serialization, the outer fence is shortened to three backticks, allowing a fence inside the content to close the block prematurely on the next parse.

javascript
import { flattenExtensions } from '@tiptap/core'
import { MarkdownManager } from '@tiptap/markdown'
import StarterKit from '@tiptap/starter-kit'

const manager = new MarkdownManager({
  extensions: flattenExtensions([StarterKit]),
})

const markdown = [
  '````markdown',
  '```js',
  'console.log("Hello");',
  '```',
  '````',
].join('\n')

const document = manager.parse(markdown)
const serialized = manager.serialize(document)
const reparsed = manager.parse(serialized)

console.log(document.content?.length) // 1
console.log(serialized)
console.log(reparsed.content?.length) // 2

The serialized Markdown is:

```markdown
```js
console.log("Hello");
```
```

The inner closing fence now closes the outer block. The final fence opens a second, empty code block. The original code content therefore loses its closing triple backticks.

Expected Behavior

Serialization should choose a fence that cannot be closed by the code block’s contents. In this example, preserving the four-backtick outer fence would produce valid Markdown:

````markdown
```js
console.log("Hello");
```
````

Parsing the serialized output should preserve the original single code block and its complete text content.

Reproducible Example URL (Optional)

No response

Additional Context (Optional)

Related to #8298, which describes the equivalent delimiter problem for inline code. This report concerns fenced code blocks in extension-code-block.