{"record":{"id":"ab753e5edb374074","repo":"n8n-io/n8n","slug":"no-file-chooser-pending-and-no-element-target-prov","errorCode":null,"errorMessage":"No file chooser pending and no element target provided","messagePattern":"No file chooser pending and no element target provided","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/@n8n/mcp-browser/src/adapters/playwright.ts","lineNumber":457,"sourceCode":"\t\t\tconst amount = options?.amount ?? 500;\n\t\t\tconst delta = options?.direction === 'up' ? -amount : amount;\n\t\t\tawait page.mouse.wheel(0, delta);\n\t\t}\n\t}\n\n\tasync upload(pageId: string, target: ElementTarget | undefined, files: string[]): Promise<void> {\n\t\tconst state = await this.ensurePage(pageId);\n\n\t\t// If a file chooser dialog is pending, use it directly\n\t\tif (state.pendingFileChooser) {\n\t\t\tawait state.pendingFileChooser.setFiles(files);\n\t\t\tstate.pendingFileChooser = undefined;\n\t\t\treturn;\n\t\t}\n\n\t\t// Otherwise, set files on the input element\n\t\tif (!target) {\n\t\t\tthrow new Error('No file chooser pending and no element target provided');\n\t\t}\n\t\tconst locator = await this.resolveLocator(pageId, target);\n\t\tawait locator.setInputFiles(files);\n\t}\n\n\tasync dialog(pageId: string, action: 'accept' | 'dismiss', text?: string): Promise<string> {\n\t\tconst state = await this.ensurePage(pageId);\n\n\t\t// If a dialog is already pending, handle it immediately\n\t\tif (state.pendingDialog) {\n\t\t\tconst dialogType = state.pendingDialog.type();\n\t\t\tif (action === 'accept') {\n\t\t\t\tawait state.pendingDialog.accept(text);\n\t\t\t} else {\n\t\t\t\tawait state.pendingDialog.dismiss();\n\t\t\t}\n\t\t\tstate.pendingDialog = undefined;\n\t\t\treturn dialogType;","sourceCodeStart":439,"sourceCodeEnd":475,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/mcp-browser/src/adapters/playwright.ts#L439-L475","documentation":"Thrown by the Playwright adapter's upload() when there is no pending file-chooser dialog AND no element target was provided. upload() first checks state.pendingFileChooser (set when a page raised a file chooser event); if none is pending, it requires a target to call locator.setInputFiles on. Without either, it cannot decide where to send the files.","triggerScenarios":"Calling playwrightAdapter.upload(pageId, target, files) where target is undefined and state.pendingFileChooser is undefined (no recent file-chooser event on the page). The caller expected a chooser to be pending but none was captured, and provided no fallback input element target.","commonSituations":"The caller clicked an upload button expecting a native file chooser, but the page used a custom (non-input) uploader so no filechooser event fired; the pendingFileChooser was already consumed by a previous upload call; the file chooser event fired on a different pageId; timing — the chooser fired before upload() was called and was cleared.","solutions":["Pass an explicit target (the <input type=\"file\"> element) so setInputFiles is used directly.","Click the upload trigger first, then call upload() immediately so the filechooser is pending when upload runs.","Ensure the page actually uses a native file input; for custom uploaders, use evaluate() to set the file via JS or switch approach.","Do not call upload() twice without a new chooser — the first call clears pendingFileChooser."],"exampleFix":"// before — no chooser pending, no target\nawait adapter.upload(pageId, undefined, ['/tmp/file.csv']);\n// throws\n\n// after — click trigger then upload, OR pass the input target\nawait adapter.click(pageId, { ref: '@uploadBtn' }); // triggers chooser\nawait adapter.upload(pageId, undefined, ['/tmp/file.csv']); // chooser now pending\n\n// OR pass the input directly\nawait adapter.upload(pageId, { ref: '@fileInput' }, ['/tmp/file.csv']);","handlingStrategy":"validation","validationCode":"function canUpload(state: { pendingFileChooser?: unknown }, target?: unknown): boolean {\n  return Boolean(state.pendingFileChooser) || Boolean(target);\n}","typeGuard":"function hasUploadTargetOrChooser(state: { pendingFileChooser?: unknown }, target?: unknown): boolean {\n  return Boolean(state.pendingFileChooser) || Boolean(target);\n}","tryCatchPattern":null,"preventionTips":["Pass an explicit input element target when no native file chooser is expected.","Click the upload trigger immediately before upload() so the chooser is pending.","Do not call upload() twice on the same chooser — the first call clears it."],"tags":["mcp-browser","playwright","upload","validation","forms"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}