Sync deletes tree when conflict encountered


Steps to reproduce

  1. Create an empty node, and sync.
  1. Go to a second computer, sync.
  2. Disconnect from the network. With that same computer, edit that node, say typing:
  • a
    • b
    • paste a TON of stuff here.
  1. Back to the first computer, delete that empty node.

  2. Back to the second computer, reconnect to the net, and sync.

Actual result

The entire tree vanishes.

Expected result

I expect those edits to be retained. Especially because it was such a trivial deletion, it shouldn’t override the edit, but even if it’s not a trivial thing that is deleted, the stuff created on the other computer should not be deleted by a delete taking place elsewhere. They don’t know what all was deleted.

If both nodes are edited, the sync process should know both nodes are edited, and create an extra conflict node so we can see both versions. A tag gets attached to each version saying we have a sync issue, and the users can review both and integrate. (Searching for #syncissue could be very helpful for a user trying to resolve the confusion.)

If one node is deleted and the other edited, the edited one should remain, and (optional) mark as a #syncissue.


Tested with Windows, Chrome, and iOS app as my two devices. I had wifi not connected for the computer. (was at Starbucks, connection not opened yet).

Additional information

No, the item that got deleted never made it into the History.

Additional comments

A very important point here: I might not know the other computer didn’t sync yet. From the current screen it says synced, but if they other was turned off, then I turn it on and it syncs, accidental deletion may occur.

Points 3 and 4 above can (probably) happen in reverse. That is, everything is synced and I delete a node. Later I go to a computer which I thought was synced, do a whole bunch of work, and then SURPRISE it all gets erased.

Implementing is a bit tricky of course. In detail, what you should have is timestamping or version stamping of nodes. When syncing a change, you need to detect not the just exact same node, but any children of that node in the case of deletion.

I am all but certain this bug has caused me to lose a non-trivial amount of data in the past. Trouble is it can be subtle - something disappears that you aren’t looking at now. And afterwards you wonder if you really typed it where you thought you did.

Team plan?
Critical Bug: Note got deleted randomly

The root cause of this issue, I think, is that the editing action doesn’t re-add an item if it’s already deleted. In theory, the now detached item was still successfully modified, it’s just that nobody can see it.

Is this a surprise though? By the last-sync-wins rule, if the last person decides to delete it, the item will get deleted, otherwise we’re basically invalidating the user’s actions, which might create inconveniences too.

When point 3 and 4 happen in reverse, this happens: when the first computer gets connection, changes from the 2nd computer come first and get applied. Then the item gets deleted. This means that changes from the first computer are retrievable in version history.

This is not ideal, but I think it’s better than preventing the deleting from happening at all. It’s a balance between accuracy and security. When point 3 and 4 are reversed, the current model is more accurate, but it runs the risk of losing some data (still retrievable in version history but you might not realize it). It’s the choice of “do I prefer to occasionally [unintentionally delete data] or [fail to delete data]”?

Generating conflict copies is probably the most fail-safe way though.

@Alan I know you’ve read this, just posting this as a reference: Dynalist concurrency model

If I understood it correctly, the case you’re raising is different from what’s being discussed in that post because the order of 3 and 4 are reversed.


I emphatically disagree. In all circumstances, to minimize accidentally deleted information is much more important than any other consideration. If I fail to delete data, I will see the data and can delete it again. If I accidentally delete data, I don’t see it missing and I cannot restore it.

“Last sync wins” is not a good rule. A sync should consider both the server and the client version equally valid, not preferring the client over the server. But it should be able to know that when the client version (portions of it) are equal or newer than the server.