unoplatform/uno · error · Error
retrieveFiles failed to find pending drag and drop data for
Error message
retrieveFiles failed to find pending drag and drop data for id ${pendingDropId}. What it means
Thrown by BrowserDragDropExtension.retrieveText when the static _idToContent Map does not contain an entry for the given pendingDropId. The _idToContent map is populated ONLY inside the 'drop' DOM event handler (line 56 of onDragDropEvent) and removed explicitly via removeId. Note: the message text incorrectly says 'retrieveFiles' even though this is the retrieveText method (copy-paste bug in the error string). This indicates the C# caller passed a drop ID that was never registered or was already consumed.
Source
Thrown at src/Uno.UI.Runtime.Skia.WebAssembly.Browser/ts/Runtime/BrowserDragDropExtension.ts:99
}
}
private static beginRetrieveItems(data: DataTransfer): Array<Promise<FileSystemHandle | File | string | null>> {
const promises: Array<Promise<FileSystemHandle | File | string | null>> = [];
for (let i = 0; i < data.items.length; i++) {
if (data.items[i].kind == "string") {
promises.push(BrowserDragDropExtension.getText(data.items[i]));
} else {
promises.push(BrowserDragDropExtension.getAsFile(data.items[i]));
}
}
return promises;
}
public static retrieveText(pendingDropId: number, itemId: number): Promise<string> {
const data = BrowserDragDropExtension._idToContent.get(pendingDropId);
if (!data) {
throw new Error(`retrieveFiles failed to find pending drag and drop data for id ${pendingDropId}.`);
}
return data[itemId] as Promise<string>;
}
public static async retrieveFiles(pendingDropId: number, itemIds: Int32Array): Promise<string> {
const data = BrowserDragDropExtension._idToContent.get(pendingDropId);
if (!data) {
throw new Error(`retrieveFiles failed to find pending drag and drop data for id ${pendingDropId}.`);
}
const selected = Array.from(itemIds).map(i => data[i] as Promise<FileSystemHandle | File>);
const fileHandles = await Promise.all(selected);
const infos = Uno.Storage.NativeStorageItem.getInfos(...fileHandles);
return JSON.stringify(infos);
}
public static removeId(id: number) {View on GitHub (pinned to 0418340488)
Solutions
- Ensure retrieveText is called exactly once per drop event, using the pendingDropId delivered by the OnNativeDropEvent dispatch (the same id set in onDragDropEvent on dragenter).
- Do not call removeId until all item content has been fully retrieved for that drop id.
- If you need to retrieve multiple items, batch them in a single retrieveFiles/retrieveText call chain before removeId.
Example fix
// before: retrieve then immediately remove BrowserDragDropExtension.retrieveText(dropId, 0); BrowserDragDropExtension.removeId(dropId); BrowserDragDropExtension.retrieveText(dropId, 1); // throws — id already removed // after: retrieve all items first, then remove const t0 = BrowserDragDropExtension.retrieveText(dropId, 0); const t1 = BrowserDragDropExtension.retrieveText(dropId, 1); await Promise.all([t0, t1]); BrowserDragDropExtension.removeId(dropId);
Defensive patterns
Strategy: validation
Validate before calling
// Before calling retrieveText, verify the drop id still has content
const data = BrowserDragDropExtension['_idToContent']?.get(pendingDropId);
if (!data) {
// drop id not staged — do not call retrieveText
return null;
} Try / catch
try {
const text = await BrowserDragDropExtension.retrieveText(dropId, itemId);
} catch (e) {
if (e.message.includes('failed to find pending drag and drop data')) {
// drop content already consumed/cleared — handle gracefully
} else { throw e; }
} Prevention
- Track which drop ids have been consumed and avoid double-retrieval.
- Call removeId only after all retrieveText/retrieveFiles calls for that id have resolved.
- Log the pendingDropId at dragenter and at retrieve time to catch mismatches early.
When it happens
Trigger: C# calls retrieveText(pendingDropId, itemId) after the drop content was already retrieved and removeId was called, or before a 'drop' event has fired (the map is only filled on drop, not dragenter), or with a stale/wrong pendingDropId.
Common situations: Double-retrieval of the same drop payload (C# calls retrieveText twice for the same drop), calling retrieve after the browser already cleared the DataTransfer, or a mismatch between the pendingDropId captured in dragenter and the one passed to retrieveText.
Related errors
- Keyboard lock is not supported by this browser.
- BrowserHtmlElement: Element with id '${id}' not found.
- A DragDropExtension has already been enabled
- The current DragDropExtension does not match the provided ar
- No pending drag and drop data.
AI-assisted analysis of unoplatform/uno@0418340488 (2026-08-13).
Data as JSON: /api/errors/ec6ef9979aba9794.
Report an issue: GitHub.