@atlaskit/tree: Cannot remove the dragging item during a drag

Hello there,

I am experiencing a bug when using @atlaskit/tree with a nested tree and drag-n-drop. I’ve been trying to figure out why this is happening without much luck and I’d appreciate some help :slight_smile:

The issue happens with @atlaskit/tree@^8.1.0 (tested with both 8.1.0 and 8.2.0).

Testcase

I prepared a test case to reproduce my setup

Instructions to reproduce (with video)

  • open the console in CodeSandbox
  • drag up items randomly and quickly from the bottom of the list

Video Instructions: https://trello-attachments.s3.amazonaws.com/5a97c704da2db30a5786bf33/604a025655db9188b7c7bf89/fa8dbb47fd6ff68653c3c1f950bb81be/drag-bug.mov

Error

Invariant failed: Cannot remove the dragging item during a drag

react-beautiful-dnd

An error has occurred while a drag is occurring.
Any existing drag will be cancelled.

> Uncaught Error: Invariant failed: Cannot remove the dragging item during a drag

👷‍ This is a development only message. It will be removed in production builds.


raw Error: Invariant failed: Cannot remove the dragging item during a drag    at invariant (https://7otlu.csb.app/node_modules/tiny-invariant/dist/tiny-invariant.esm.js:14:9)

    at Object.unregisterDraggable (https://7otlu.csb.app/node_modules/react-beautiful-dnd-next/dist/react-beautiful-dnd.esm.js:3489:123)

    at eval (https://7otlu.csb.app/node_modules/react-beautiful-dnd-next/dist/react-beautiful-dnd.esm.js:6325:22)
    at HTMLUnknownElement.callCallback (https://7otlu.csb.app/node_modules/react-dom/cjs/react-dom.development.js:2746:18)
    at Object.invokeGuardedCallbackDev (https://7otlu.csb.app/node_modules/react-dom/cjs/react-dom.development.js:2770:20)
    at invokeGuardedCallback (https://7otlu.csb.app/node_modules/react-dom/cjs/react-dom.development.js:2804:35)
    at safelyCallDestroy (https://7otlu.csb.app/node_modules/react-dom/cjs/react-dom.development.js:13808:9)
    at commitUnmount (https://7otlu.csb.app/node_modules/react-dom/cjs/react-dom.development.js:14167:25)
    at **unmountHostComponents** (https://7otlu.csb.app/node_modules/react-dom/cjs/react-dom.development.js:14423:11)
    at commitDeletion (https://7otlu.csb.app/node_modules/react-dom/cjs/react-dom.development.js:14448:9)
    at commitMutationEffects (https://7otlu.csb.app/node_modules/react-dom/cjs/react-dom.development.js:15733:15)
    at HTMLUnknownElement.callCallback (https://7otlu.csb.app/node_modules/react-dom/cjs/react-dom.development.js:2746:18)
    at Object.invokeGuardedCallbackDev (https://7otlu.csb.app/node_modules/react-dom/cjs/react-dom.development.js:2770:20)
    at invokeGuardedCallback (https://7otlu.csb.app/node_modules/react-dom/cjs/react-dom.development.js:2804:35)
    at commitRootImpl (https://7otlu.csb.app/node_modules/react-dom/cjs/react-dom.development.js:15545:13)
    at unstable_runWithPriority (https://7otlu.csb.app/node_modules/scheduler/cjs/scheduler.development.js:646:12)
    at runWithPriority$1 (https://7otlu.csb.app/node_modules/react-dom/cjs/react-dom.development.js:7417:14)
    at commitRoot (https://7otlu.csb.app/node_modules/react-dom/cjs/react-dom.development.js:15466:7)
    at performSyncWorkOnRoot (https://7otlu.csb.app/node_modules/react-dom/cjs/react-dom.development.js:15031:7)
    at eval (https://7otlu.csb.app/node_modules/react-dom/cjs/react-dom.development.js:7457:30)
    at unstable_runWithPriority (https://7otlu.csb.app/node_modules/scheduler/cjs/scheduler.development.js:646:12)
    at runWithPriority$1 (https://7otlu.csb.app/node_modules/react-dom/cjs/react-dom.development.js:7417:14)
    at flushSyncCallbackQueueImpl (https://7otlu.csb.app/node_modules/react-dom/cjs/react-dom.development.js:7453:13)
    at flushSyncCallbackQueue (https://7otlu.csb.app/node_modules/react-dom/cjs/react-dom.development.js:7443:7)
    at scheduleUpdateOnFiber (https://7otlu.csb.app/node_modules/react-dom/cjs/react-dom.development.js:14776:13)
    at Object.enqueueSetState (https://7otlu.csb.app/node_modules/react-dom/cjs/react-dom.development.js:8288:9)
    at PureTree.Component.setState (https://7otlu.csb.app/node_modules/react/cjs/react.development.js:186:20)
    at _callee$ (https://7otlu.csb.app/src/App.js:223:23)
    at tryCatch (eval at z (https://codesandbox.io/static/js/sandbox.f48617fa5.js:1:99243), <anonymous>:63:40)
    at Generator.invoke [as _invoke] (eval at z (https://codesandbox.io/static/js/sandbox.f48617fa5.js:1:99243), <anonymous>:293:22)
    at Generator.eval [as next] (eval at z (https://codesandbox.io/static/js/sandbox.f48617fa5.js:1:99243), <anonymous>:118:21)
    at asyncGeneratorStep (eval at z (https://codesandbox.io/static/js/sandbox.f48617fa5.js:1:99243), <anonymous>:3:24)
    at _next (eval at z (https://codesandbox.io/static/js/sandbox.f48617fa5.js:1:99243), <anonymous>:25:9) 
    in ErrorBoundary (created by DragDropContext)
    in DragDropContext (created by Tree)
    in Tree (created by PureTree)
    in PureTree (created by App)
    in App

Details

In contrast with the example in the docs I don’t keep the tree in local state because my component is (mostly) controlled (tree comes from props) and on drag end I need to persist the new tree remotely (multi users app).

I have some logic to do an optimistic update (the bits that involve pendingMovement) and pause rendering (shouldComponentUpdate returns false) while the app is persisting the changes. Once changes are persisted the drag end handler resets pendingMovement and re-enables rendering.

Probably something causes the component to unmount and mount again while dragging? But I cannot figure how and what.

Things I have tried and that didn’t help

  • Disable dragging (with isDragEnabled and with pointer-events: none) while saving (pendingMovement !== null)
  • Lift pendingMovement up and avoid computing the tree conditionally within render
  • Made onDragEnd sync and set pendingMovement and disableRendering in there and move the rest to an async componentDidUpdate
  • Added an ErrorBoundary which seems to have no effect: it doesn’t catch the error

Unrelated

With this setup sometimes I also get this error:

react-beautiful-dnd.esm.js:111 Uncaught TypeError: Cannot read property 'path' of undefined
    at getFlatItemPath (flat-tree.js:3)
    at getDestinationPath (flat-tree.js:32)
    at Tree._this.calculateEffectivePath (Tree.js:86)
    at eval (Tree.js:131)
    at Draggable (react-beautiful-dnd.esm.js:7868)
    at renderWithHooks (react-dom.development.js:16240)
    at updateFunctionComponent (react-dom.development.js:18327)
    at beginWork$1 (react-dom.development.js:20150)

Thank you in advance for your help!

Hey Giuseppe! Thanks so much for bringing this to our attention.

I’ve passed this onto the team that owns this component — we’ll do our best to help you out :relaxed: Will keep you updated!