Skip to content

fix: don't crash the tab when upload_file targets a chooser-opening element#2311

Open
serhiizghama wants to merge 3 commits into
ChromeDevTools:mainfrom
serhiizghama:fix/upload-file-chooser-element
Open

fix: don't crash the tab when upload_file targets a chooser-opening element#2311
serhiizghama wants to merge 3 commits into
ChromeDevTools:mainfrom
serhiizghama:fix/upload-file-chooser-element

Conversation

@serhiizghama

Copy link
Copy Markdown
Contributor

Fixes #2310. upload_file calls handle.uploadFile() on whatever element you pass it first, and only falls back to the file chooser if that throws. But when the element is a proxy that opens the chooser (a button calling input.click(), which is how most real upload UIs work), uploadFile doesn't throw — puppeteer reads element.multiple (undefined on a button, no error) and then sends DOM.setFileInputFiles to a non-input node, which kills the renderer with RESULT_CODE_KILLED_BAD_MESSAGE. The try/catch can't help because the tab is already gone, and the tool then reports a misleading "element no longer exists" error.

The tool's own schema documents the chooser-opening element as supported, so the fix is to stop probing with uploadFile: check whether the element is actually an <input type=file> and only use the direct path for those. Everything else goes straight to the click + waitForFileChooser path it was always meant to use.

All three existing upload_file tests still pass. Added one for a non-file <input> to lock in that the check is type === 'file', not just instanceof HTMLInputElement — otherwise a text input would still be routed into the crashing path.

Calling uploadFile on a proxy element (e.g. a button that opens the
chooser via input.click()) sends DOM.setFileInputFiles to a non-input
node, which kills the renderer (RESULT_CODE_KILLED_BAD_MESSAGE). The
previous try/catch could not recover because the tab was already dead.
Check whether the element is an <input type=file> first and drive the
file chooser explicitly for everything else.
@OrKoN

OrKoN commented Jul 7, 2026

Copy link
Copy Markdown
Collaborator

Thanks for the PR but I think the test passes without the fix (please see #2313)

The previous test passed on unmodified source: the in-process browser
throws when uploadFile hits a non-file element, so the old code recovered
via the chooser and the assertion held either way. Stub uploadFile to a
silent no-op so a chooser-opening button behaves like it does in headful
Chrome (no throw, file never set), then assert uploadFile is never called
on it and the chooser path delivers the file. Reverting the fix now fails
the test.
@serhiizghama

Copy link
Copy Markdown
Contributor Author

You're right — the old test passed without the fix. The in-process test browser throws when uploadFile hits a non-file element, so the code recovered via the chooser and the assertion held either way. That doesn't happen in real headful Chrome, where uploadFile on a chooser-opening element doesn't throw — it kills the renderer and the file is never set.

Reworked the test to reproduce that: it stubs uploadFile on the button to a silent no-op (matching production, where probing the proxy element uploads nothing), then asserts uploadFile is never called on the non-file element and that the chooser path actually delivers the file. Reverting the source fix now fails it. Full suite green.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

upload_file on a chooser-opening element crashes the tab with RESULT_CODE_KILLED_BAD_MESSAGE

2 participants