Iām building a Dynalist MCP server that lets AI assistants interact with Dynalist via the public API. While implementing node deletion, I discovered that the APIās delete action does not cascade-delete child nodes. To prevent orphaning, Iām having to read the full subtree and recursively delete all descendants bottom-up before deleting the parent.
Steps to reproduce
- Using the API (
/api/v1/doc/edit), insert a parent node under root withaction: "insert". - Insert a child node under that parent with
action: "insert". - Delete the parent node with
action: "delete"(only specifying the parentāsnode_id). - Read the document with
/api/v1/doc/readand inspect thenodesarray.
Expected result
The parent node and all of its descendants should be removed from the nodes array, consistent with how the web UI handles deletion.
Actual result
The parent node is removed, but the child node remains in the nodes array. No other node references it in its children array, so it is orphaned. The node is unreachable but still present in the document data. Over time, repeated API deletions of nodes with children silently accumulate orphans and inflate the document size.
Environment
N/A. This is a server-side API bug, reproducible via curl from any environment.
Additional information
The third-party Android app QuickDynalist is also affected. It sends a single delete action for the parent node only. The app masks the problem by removing descendants from its local database, so the UI appears correct, but orphans persist on the server.
Another user reported the same underlying issue in the context of bulk deletion: Bulk delete
500 top-level nodes shouldnāt be that common. If you delete a top level item, all child items are removed and it counts as 1 operation.
@shida this response to the above post made it sound like a delete should clean-up all of its children? But it doesnāt seem like thatās fully the case.
A server-side orphan garbage collector would resolve this cleanly. It would retroactively clean up all orphans already accumulated across every API consumer, not just prevent future ones. The alternative of expecting every client to implement recursive bottom-up deletion is fragile and clearly not happening in practice (see QuickDynalist above).