[Bug] MCP update_document patch mode silently drops content after checkbox lists

Status Open
Reported on v2.1.233
Maintainer reply None cached
Activity 0 comments · opened Aug 20, 2026

Bug Description
claude.ai wiki (Outline) MCP: update_document editMode "patch" silently discards every block after a checkbox list in the replacement text.

This is silent data loss. No error is returned, the call reports success, "revision" increments, and "tasks.total" updates to match the new checkbox list, so every available signal indicates the write landed intact. The dropped content is only discoverable by reading the returned body and checking your own text is present, or later when a findText anchor unexpectedly fails to match.

REPRODUCTION

  1. Create a draft:

create_document
title: "repro"
publish: false
text:
Intro.

  • [ ] alpha
  • [x] beta
  1. Patch the checkbox list, updating the list and adding a paragraph in the same call:

update_document
editMode: "patch"
findText: "- [ ] alpha\n- [x] beta"
text: "- [x] alpha\n- [ ] gamma\n\nTAIL paragraph."

EXPECTED: list becomes 2 items and "TAIL paragraph." is inserted after it.

ACTUAL: list becomes 2 items. "TAIL paragraph." is absent. Response returns success, revision increments to 2, tasks.total updates to 2.

TRIGGER CONDITIONS

The loss requires BOTH of these at once:

  • findText matches a checkbox list, AND
  • the replacement text is a checkbox list followed by one or more other blocks.

Everything after the leading list is discarded, including paragraphs and headings.

NEGATIVE CONTROLS (all behave correctly)

findText = checkbox list, text = prose only content kept
findText = checkbox list, text = two paragraphs both kept
findText = plain paragraph, text = checkbox list + prose both kept
create_document, list + prose kept
update_document replace, list + prose + heading kept
WHY THIS IS THE CONNECTOR AND NOT OUTLINE

editMode and findText are not part of Outline's API. Outline's documents.update accepts text plus an append flag and has no find-and-replace capability, so the substring match and splice are performed by the connector before Outline is called.

The controls above confirm this from the other direction: the same markdown survives create_document and survives editMode "replace", both of which exercise Outline's real update endpoint and its real markdown to ProseMirror parser. Only the patch path loses content. Outline never receives a request capable of producing this result, so outline/outline is not the right tracker.

For completeness, Outline does have a separate closed issue in this code area, #10963 "Crash in checkboxes.ts when parsing backtick-wrapped checkboxes in lists". That is a crash on different input, and the create and replace controls show that parser handles the input above correctly. It does not appear related.

IMPACT

Checkbox lists are the standard task-tracking pattern in Outline, so "patch a document whose body is a checkbox list, updating the list and its surrounding notes in one call" is a common edit rather than an edge case. Because the failure is silent and the success signals are all positive, content can be lost repeatedly before anyone notices.

WORKAROUND

Never send a checkbox list plus other blocks in a single list-anchored patch. Either split it into two calls, or anchor findText on the heading that follows the region and prepend the new content ahead of it. Then verify the returned body actually contains the new text; the revision bump is not proof.

Environment Info

  • Platform: win32
  • Terminal: null
  • Version: 2.1.233
  • Feedback ID: d055bf72-32ad-4213-9eb3-1d7f37069d06

Errors

[{"error":"TelemetrySafeError: VirtualMessageList: itemKeys/messages length desync (keys=1346 messages=1345 range=[1311,1345))\n    at AGE (B:/~BUN/root/cli:22830:33325)\n    at Vuh (B:/~BUN/root/cli:22830:26297)\n    at ko (B:/~BUN/root/cli:13184:21380)\n    at fs (B:/~BUN/root/cli:13184:40481)\n    at Xu (B:/~BUN/root/cli:13184:51405)\n    at lCe (B:/~BUN/root/cli:13184:89090)\n    at FSe (B:/~BUN/root/cli:13184:88039)\n    at $Se (B:/~BUN/root/cli:13184:87858)\n    at IC (B:/~BUN/root/cli:13184:84117)\n    at et (B:/~BUN/root/cli:13184:6675)","timestamp":"2026-08-19T04:02:59.886Z"}]

View original on GitHub ↗