Bug: update_page silently drops images due to mismatched Tiptap Image extension config #4

Closed
opened 2026-03-11 03:10:44 -06:00 by foogunlana · 0 comments
foogunlana commented 2026-03-11 03:10:44 -06:00 (Migrated from github.com)

Description

When using update_page with markdown content containing images (e.g. ![alt](/api/files/id/file.png)), the images are silently dropped from the page content. The text content updates fine, but all image nodes are missing from the resulting Tiptap/ProseMirror document.

Root Cause

In src/lib/tiptap-extensions.ts, the Image extension is configured with inline: true:

Image.configure({
  inline: true,
})

However, Docmost's actual image extension (source) defines images as block-level nodes:

inline: false,
group: "block",

When the MCP's update_page pipeline runs (markdown → marked.parse() → HTML → generateJSON() → Tiptap JSON → Yjs), it creates inline image nodes inside paragraphs. But Docmost's Yjs document expects block-level image nodes. The Yjs merge silently discards the mismatched nodes.

Steps to Reproduce

  1. Upload an image to a page via Docmost's POST /api/files/upload endpoint
  2. Use update_page with markdown containing ![alt text](/api/files/{id}/{filename})
  3. Observe: the text content updates, but all images are missing

Expected Behavior

Images in the markdown should be preserved as block-level image nodes in the page content.

Fix

Change inline: true to inline: false in src/lib/tiptap-extensions.ts:

Image.configure({
  inline: false,
})

This aligns the MCP's Tiptap schema with Docmost's actual editor schema.

Workaround

Use the /pages/import endpoint instead of update_page for content that includes images.

## Description When using `update_page` with markdown content containing images (e.g. `![alt](/api/files/id/file.png)`), the images are silently dropped from the page content. The text content updates fine, but all image nodes are missing from the resulting Tiptap/ProseMirror document. ## Root Cause In `src/lib/tiptap-extensions.ts`, the Image extension is configured with `inline: true`: ```ts Image.configure({ inline: true, }) ``` However, Docmost's actual image extension ([source](https://github.com/docmost/docmost/blob/main/packages/editor-ext/src/lib/image/image.ts)) defines images as **block-level** nodes: ```ts inline: false, group: "block", ``` When the MCP's `update_page` pipeline runs (markdown → `marked.parse()` → HTML → `generateJSON()` → Tiptap JSON → Yjs), it creates inline image nodes inside paragraphs. But Docmost's Yjs document expects block-level image nodes. The Yjs merge silently discards the mismatched nodes. ## Steps to Reproduce 1. Upload an image to a page via Docmost's `POST /api/files/upload` endpoint 2. Use `update_page` with markdown containing `![alt text](/api/files/{id}/{filename})` 3. Observe: the text content updates, but all images are missing ## Expected Behavior Images in the markdown should be preserved as block-level image nodes in the page content. ## Fix Change `inline: true` to `inline: false` in `src/lib/tiptap-extensions.ts`: ```ts Image.configure({ inline: false, }) ``` This aligns the MCP's Tiptap schema with Docmost's actual editor schema. ## Workaround Use the `/pages/import` endpoint instead of `update_page` for content that includes images.
Sign in to join this conversation.