[GH-ISSUE #8486] [Bug] documentToMarkdown destructively mutates the source Document on indented content #3880

Closed
opened 2026-03-23 21:33:50 +00:00 by mirror · 1 comment
Owner

Originally created by @ContextFound on GitHub (Feb 18, 2026).
Original GitHub issue: https://github.com/AppFlowy-IO/AppFlowy/issues/8486

Bug Description

I have a Flutter for web app that uses the AppFlowy editor, and it has a debounced periodic save that does a documentToMarkdown() and saves that MD to a noSQL DB (Firestore). When I create an indented list item, the save runs and the sub-items are no longer rendered. They exist in the markdown section behind the scenes, but not visible (no blank line, anything).
I believe the root problem is that documentToMarkdown outputs correct contents, but in the process it orphans and disposes of child items in the source document. Since I'm still displaying the source in the UI, the children are stripped from the editor view.

How to Reproduce

import 'package:appflowy_editor/appflowy_editor.dart';

void main() {
  // 1. Create a document with a nested bulleted list
  final document = Document(
    root: pageNode(
      children: [
        bulletedListNode(
          text: 'Parent item',
          children: [
            bulletedListNode(text: 'Child item'),
          ],
        ),
      ],
    ),
  );

  // 2. Verify children exist
  final parentNode = document.root.children.first;
  print('Before: ${parentNode.children.length} children');
  // Output: Before: 1 children

  // 3. Convert to markdown
  final markdown = documentToMarkdown(document);
  print('Markdown:\n$markdown');
  // Output (correct):
  // * Parent item
  // 	* Child item

  // 4. Check children again
  print('After: ${parentNode.children.length} children');
  // Output: After: 0 children  <-- CHILDREN ARE GONE
}

Expected Behavior

Suggested Fix

In DocumentMarkdownEncoder.convertNodes(), deep-copy the nodes before reparenting:
String convertNodes( List<Node> nodes, { bool withIndent = false, }) { final result = convert( Document(root: pageNode(children: nodes.map((n) => n.copyWith()))), ); // ... }

Operating System

Mac + Chrome

AppFlowy Version(s)

^6.2.0

Screenshots

No response

Additional Context

No response

Originally created by @ContextFound on GitHub (Feb 18, 2026). Original GitHub issue: https://github.com/AppFlowy-IO/AppFlowy/issues/8486 ### Bug Description I have a Flutter for web app that uses the AppFlowy editor, and it has a debounced periodic save that does a documentToMarkdown() and saves that MD to a noSQL DB (Firestore). When I create an indented list item, the save runs and the sub-items are no longer rendered. They exist in the markdown section behind the scenes, but not visible (no blank line, anything). I believe the root problem is that documentToMarkdown outputs correct contents, but in the process it orphans and disposes of child items in the source document. Since I'm still displaying the source in the UI, the children are stripped from the editor view. ### How to Reproduce ``` import 'package:appflowy_editor/appflowy_editor.dart'; void main() { // 1. Create a document with a nested bulleted list final document = Document( root: pageNode( children: [ bulletedListNode( text: 'Parent item', children: [ bulletedListNode(text: 'Child item'), ], ), ], ), ); // 2. Verify children exist final parentNode = document.root.children.first; print('Before: ${parentNode.children.length} children'); // Output: Before: 1 children // 3. Convert to markdown final markdown = documentToMarkdown(document); print('Markdown:\n$markdown'); // Output (correct): // * Parent item // * Child item // 4. Check children again print('After: ${parentNode.children.length} children'); // Output: After: 0 children <-- CHILDREN ARE GONE } ``` ### Expected Behavior ## Suggested Fix In DocumentMarkdownEncoder.convertNodes(), deep-copy the nodes before reparenting: `String convertNodes( List<Node> nodes, { bool withIndent = false, }) { final result = convert( Document(root: pageNode(children: nodes.map((n) => n.copyWith()))), ); // ... }` ### Operating System Mac + Chrome ### AppFlowy Version(s) ^6.2.0 ### Screenshots _No response_ ### Additional Context _No response_
Author
Owner

@richardshiue commented on GitHub (Feb 23, 2026):

Hi @ContextFound, let me confirm this with the team to see if this is intended. In the mean time, can you deep copy before calling documentToMarkdown? Would that resolve your issue?

<!-- gh-comment-id:3942565866 --> @richardshiue commented on GitHub (Feb 23, 2026): Hi @ContextFound, let me confirm this with the team to see if this is intended. In the mean time, can you deep copy before calling documentToMarkdown? Would that resolve your issue?
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
AppFlowy-IO/AppFlowy#3880
No description provided.