fix(extension): file upload via file-chooser interception (#2108)#2110
Open
matthew6688 wants to merge 3 commits into
Open
fix(extension): file upload via file-chooser interception (#2108)#2110matthew6688 wants to merge 3 commits into
matthew6688 wants to merge 3 commits into
Conversation
…2108) DOM.setFileInputFiles called directly with a nodeId is rejected with -32000 "Not allowed" for chrome.debugger-attached clients (Chromium #928255, since Chrome 72), breaking browser upload / page.uploadFiles() on every site through the extension bridge. Replace the direct call with the flow Chrome permits: enable Page.setInterceptFileChooserDialog, click the resolved input with userGesture, take the backendNodeId from the resulting Page.fileChooserOpened event, and answer the chooser with DOM.setFileInputFiles({files, backendNodeId}). Hardening: per-tab in-flight guard (interception is per-tab, overlapping calls would steal each other's event), defensive interception reset at start, selectSingle vs multi-file check, remote object group released, interception always disabled in finally. Ref: codex round /tmp/codex-round-01-opencli-filechooser.md Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Codex audit follow-up: assert the fileChooserOpened listener is removed on the timeout and missing-backendNodeId paths, not just on success. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #2108.
Problem
opencli browser <session> upload,page.uploadFiles(), andpage.setFileInput()fail on every site with{"code":-32000,"message":"Not allowed"}when running through the Browser Bridge extension. Root cause: since Chrome 72 (Chromium #928255),DOM.setFileInputFilescalled directly with anodeIdis rejected for chrome.debugger-attached clients — it is only permitted as an answer to a file chooser Chrome itself opened. This breaks file/image attachment for all adapters (perplexityask --attach,chatgpt image --image,project-file-add, gemini, google-ai, …).Fix
extension/src/cdp.ts setFileInputFiles()now uses the file-chooser interception flow Chrome permits under chrome.debugger (same architecture as hangwin/mcp-chrome#145):DOM.enable+Page.enableDOM.querySelector→DOM.resolveNode, error contract unchanged)chrome.debugger.onEventlistener forPage.fileChooserOpened(filtered by tabId)Page.setInterceptFileChooserDialog({enabled: true})— suppresses the native dialogRuntime.callFunctionOnwithuserGesture: truebackendNodeIdfrom the event and answer withDOM.setFileInputFiles({files, backendNodeId})finally: interception disabled, listener removed, object group releasedHardening beyond the happy path:
fileChooserOpenedevent, so a second concurrent upload on the same tab is rejected with a clear errormode: selectSingle+ multiple files → explicit errorbackendNodeIdin the event → explicit error (falling back to the queried nodeId would just hit the same-32000)The CLI side is untouched: the direct-CDP path in
base-page.ts setFileInputBySelector()still applies to non-extension backends, where the direct call is allowed.Evidence
Unit: 5 new tests in
extension/src/cdp.test.tspinning the contract (eventbackendNodeIdused — not the querySelector nodeId; intercept→click→setFiles ordering;userGesture: true; finally-disable on success/error/timeout; concurrency guard). Extension suite 23/23 green;npx tsc --noEmitclean at root. (The 6src/cli.test.tsfailures innpm testreproduce identically onmainin my environment — unrelated.)Live (macOS, Chrome for Testing 149, opencli CLI 1.8.6 daemon, extension loaded unpacked):
.txtto<input type=file>changefires89504e470d0a1a0a,type=image/png, full size%PDF, full sizes{"code":-32000,"message":"Not allowed"}Verification read the first 8 bytes of each
Filein-page (file.slice(0,8).arrayBuffer()) to confirm Chrome attached real file content from disk, not just metadata.Extension version bumped to 1.0.23 (separate commit, matching prior bump convention);
dist/rebuilt from source.🤖 Generated with Claude Code