microsoft/playwright · error · NonRecoverableDOMError
Drop target did not accept the drop — its dragover handler d
Error message
Drop target did not accept the drop — its dragover handler did not call preventDefault()
What it means
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.
Source
Thrown at packages/playwright-core/src/server/dom.ts:718
bubbles: true,
cancelable: true,
composed: true,
clientX: point.x,
clientY: point.y,
dataTransfer: dt,
});
element.dispatchEvent(makeEvent('dragenter'));
const over = makeEvent('dragover');
element.dispatchEvent(over);
if (!over.defaultPrevented) {
element.dispatchEvent(makeEvent('dragleave'));
return 'not-accepted' as const;
}
element.dispatchEvent(makeEvent('drop'));
return 'accepted' as const;
}, { payloads, data, point }));
if (result === 'not-accepted')
throw new NonRecoverableDOMError('Drop target did not accept the drop — its dragover handler did not call preventDefault()');
} finally {
if (disposeHandle)
handle.dispose();
}
}, { ...options, waitAfter: 'disabled' });
}
async _setInputFiles(progress: Progress, items: InputFilesItems): Promise<'error:notconnected' | 'done'> {
const { filePayloads, localPaths, localDirectory } = items;
const multiple = filePayloads && filePayloads.length > 1 || localPaths && localPaths.length > 1;
const result = await progress.race(this._evaluateHandleInUtility(([injected, node, { multiple, directoryUpload }]): Element | undefined => {
const element = injected.retarget(node, 'follow-label');
if (!element)
return;
if (element.tagName !== 'INPUT')
throw injected.createStacklessError('Node is not an HTMLInputElement');
const inputElement = element as HTMLInputElement;
if (multiple && !inputElement.multiple && !inputElement.webkitdirectory)View on GitHub (pinned to c8fc3bf8d3)
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.
Example fix
// before
await page.locator('#item').dragTo(page.locator('#not-a-dropzone')); // throws
// after
await page.locator('#item').dragTo(page.locator('#dropzone')); // dragover calls preventDefault Defensive patterns
Strategy: validation
Validate before calling
// Verify the target is a real drop zone before dropping.
const accepts = await page.locator('#dropzone').evaluate(el => {
let ok = false;
el.addEventListener('dragover', e => { ok = true; }, { once: true });
return ok;
});
await page.locator('#item').dragTo(page.locator('#dropzone')); Prevention
- 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.
When it happens
Trigger: 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).
Common situations: 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.
Related errors
- Cannot set input files to detached input element
- Unable to adopt element handle from a different document
- Element is not visible
- Element is outside of the viewport
- Did not find some options
AI-assisted analysis of microsoft/playwright@c8fc3bf8d3 (2026-08-12).
Data as JSON: /api/errors/a2ad43b38c97e1bf.
Report an issue: GitHub.