{"record":{"id":"a2ad43b38c97e1bf","repo":"microsoft/playwright","slug":"drop-target-did-not-accept-the-drop-its-dragover","errorCode":null,"errorMessage":"Drop target did not accept the drop — its dragover handler did not call preventDefault()","messagePattern":"Drop target did not accept the drop — its dragover handler did not call preventDefault\\(\\)","errorType":"exception","errorClass":"NonRecoverableDOMError","httpStatus":null,"severity":"error","filePath":"packages/playwright-core/src/server/dom.ts","lineNumber":718,"sourceCode":"            bubbles: true,\n            cancelable: true,\n            composed: true,\n            clientX: point.x,\n            clientY: point.y,\n            dataTransfer: dt,\n          });\n          element.dispatchEvent(makeEvent('dragenter'));\n          const over = makeEvent('dragover');\n          element.dispatchEvent(over);\n          if (!over.defaultPrevented) {\n            element.dispatchEvent(makeEvent('dragleave'));\n            return 'not-accepted' as const;\n          }\n          element.dispatchEvent(makeEvent('drop'));\n          return 'accepted' as const;\n        }, { payloads, data, point }));\n        if (result === 'not-accepted')\n          throw new NonRecoverableDOMError('Drop target did not accept the drop — its dragover handler did not call preventDefault()');\n      } finally {\n        if (disposeHandle)\n          handle.dispose();\n      }\n    }, { ...options, waitAfter: 'disabled' });\n  }\n\n  async _setInputFiles(progress: Progress, items: InputFilesItems): Promise<'error:notconnected' | 'done'> {\n    const { filePayloads, localPaths, localDirectory } = items;\n    const multiple = filePayloads && filePayloads.length > 1 || localPaths && localPaths.length > 1;\n    const result = await progress.race(this._evaluateHandleInUtility(([injected, node, { multiple, directoryUpload }]): Element | undefined => {\n      const element = injected.retarget(node, 'follow-label');\n      if (!element)\n        return;\n      if (element.tagName !== 'INPUT')\n        throw injected.createStacklessError('Node is not an HTMLInputElement');\n      const inputElement = element as HTMLInputElement;\n      if (multiple && !inputElement.multiple && !inputElement.webkitdirectory)","sourceCodeStart":700,"sourceCodeEnd":736,"githubUrl":"https://github.com/microsoft/playwright/blob/c8fc3bf8d31542d59b4d4d9eaab1df93ff541dc6/packages/playwright-core/src/server/dom.ts#L700-L736","documentation":"HTML5 drag-and-drop requires the drop target's dragover handler to call event.preventDefault() to signal that it accepts the drop. The injected drop logic dispatches dragenter then dragover; if dragover's default is not prevented, it dispatches dragleave and returns 'not-accepted', and Playwright throws NonRecoverableDOMError. This mirrors real browser behavior: without preventDefault on dragover, the drop event never fires.","triggerScenarios":"Calling locator.drop() / elementHandle.drop() onto an element that is not a registered drop zone — its dragover handler does not call preventDefault (or it has no handler at all).","commonSituations":"Testing drag onto a plain <div> that the app only makes a drop target under certain conditions; targeting the wrong element; the app uses a custom (non-HTML5) drag library that ignores synthetic DnD events.","solutions":["Target an element whose dragover handler calls preventDefault (a real drop zone).","Ensure the app has registered the drop target before the drop call (e.g. enter a drag mode first).","If the app uses a custom drag library, drive it via mouse moves/down/up instead of the HTML5 drop API.","Verify the target with page.evaluate: check it has an active dragover→preventDefault listener."],"exampleFix":"// before\nawait page.locator('#item').dragTo(page.locator('#not-a-dropzone')); // throws\n// after\nawait page.locator('#item').dragTo(page.locator('#dropzone')); // dragover calls preventDefault","handlingStrategy":"validation","validationCode":"// Verify the target is a real drop zone before dropping.\nconst accepts = await page.locator('#dropzone').evaluate(el => {\n  let ok = false;\n  el.addEventListener('dragover', e => { ok = true; }, { once: true });\n  return ok;\n});\nawait page.locator('#item').dragTo(page.locator('#dropzone'));","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Drop only onto elements whose dragover handler calls preventDefault.","For custom drag libraries, drive pointer moves manually instead of the HTML5 drop API.","Make sure the app has activated the drop zone before the drop."],"tags":["drag-and-drop","html5-dnd","dom"],"backgroundTag":null,"analyzedSha":"c8fc3bf8d31542d59b4d4d9eaab1df93ff541dc6","analyzedAt":"2026-08-12T07:26:36.950Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}