{"record":{"id":"ec6ef9979aba9794","repo":"unoplatform/uno","slug":"retrievefiles-failed-to-find-pending-drag-and-drop","errorCode":null,"errorMessage":"retrieveFiles failed to find pending drag and drop data for id ${pendingDropId}.","messagePattern":"retrieveFiles failed to find pending drag and drop data for id (.+?)\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/Uno.UI.Runtime.Skia.WebAssembly.Browser/ts/Runtime/BrowserDragDropExtension.ts","lineNumber":99,"sourceCode":"\t\t\t}\n\t\t}\n\n\t\tprivate static beginRetrieveItems(data: DataTransfer): Array<Promise<FileSystemHandle | File | string | null>> {\n\t\t\tconst promises: Array<Promise<FileSystemHandle | File | string | null>> = [];\n\t\t\tfor (let i = 0; i < data.items.length; i++) {\n\t\t\t\tif (data.items[i].kind == \"string\") {\n\t\t\t\t\tpromises.push(BrowserDragDropExtension.getText(data.items[i]));\n\t\t\t\t} else {\n\t\t\t\t\tpromises.push(BrowserDragDropExtension.getAsFile(data.items[i]));\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn promises;\n\t\t}\n\n\t\tpublic static retrieveText(pendingDropId: number, itemId: number): Promise<string> {\n\t\t\tconst data = BrowserDragDropExtension._idToContent.get(pendingDropId);\n\t\t\tif (!data) {\n\t\t\t\tthrow new Error(`retrieveFiles failed to find pending drag and drop data for id ${pendingDropId}.`);\n\t\t\t}\n\n\t\t\treturn data[itemId] as Promise<string>;\n\t\t}\n\n\t\tpublic static async retrieveFiles(pendingDropId: number, itemIds: Int32Array): Promise<string> {\n\t\t\tconst data = BrowserDragDropExtension._idToContent.get(pendingDropId);\n\t\t\tif (!data) {\n\t\t\t\tthrow new Error(`retrieveFiles failed to find pending drag and drop data for id ${pendingDropId}.`);\n\t\t\t}\n\n\t\t\tconst selected = Array.from(itemIds).map(i => data[i] as Promise<FileSystemHandle | File>);\n\t\t\tconst fileHandles = await Promise.all(selected);\n\t\t\tconst infos = Uno.Storage.NativeStorageItem.getInfos(...fileHandles);\n\t\t\treturn JSON.stringify(infos);\n\t\t}\n\n\t\tpublic static removeId(id: number) {","sourceCodeStart":81,"sourceCodeEnd":117,"githubUrl":"https://github.com/unoplatform/uno/blob/04183404888ea21b4e5bfa3493e8d5f15e972c3a/src/Uno.UI.Runtime.Skia.WebAssembly.Browser/ts/Runtime/BrowserDragDropExtension.ts#L81-L117","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before: retrieve then immediately remove\nBrowserDragDropExtension.retrieveText(dropId, 0);\nBrowserDragDropExtension.removeId(dropId);\nBrowserDragDropExtension.retrieveText(dropId, 1); // throws — id already removed\n\n// after: retrieve all items first, then remove\nconst t0 = BrowserDragDropExtension.retrieveText(dropId, 0);\nconst t1 = BrowserDragDropExtension.retrieveText(dropId, 1);\nawait Promise.all([t0, t1]);\nBrowserDragDropExtension.removeId(dropId);","handlingStrategy":"validation","validationCode":"// Before calling retrieveText, verify the drop id still has content\nconst data = BrowserDragDropExtension['_idToContent']?.get(pendingDropId);\nif (!data) {\n    // drop id not staged — do not call retrieveText\n    return null;\n}","typeGuard":null,"tryCatchPattern":"try {\n    const text = await BrowserDragDropExtension.retrieveText(dropId, itemId);\n} catch (e) {\n    if (e.message.includes('failed to find pending drag and drop data')) {\n        // drop content already consumed/cleared — handle gracefully\n    } else { throw e; }\n}","preventionTips":["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."],"tags":["wasm","drag-and-drop","browser","typescript","skia-wasm-browser"],"backgroundTag":null,"analyzedSha":"04183404888ea21b4e5bfa3493e8d5f15e972c3a","analyzedAt":"2026-08-13T21:08:11.651Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}