Skip to content

Chrome plugin file upload setFiles fails with Not allowed and upload forms can hang #21597

Open

Description

@markmdev

Summary

The Chrome plugin can connect to Chrome and navigate normally, but repeatedly hangs/timeouts on an authenticated invoice upload form when trying to inspect controls, upload files, or capture a visual screenshot.

This blocked completing a browser task that required uploading receipt images through @Chrome only.

What happened

Using the Chrome plugin in Codex Desktop:

  • browser.user.openTabs() worked.
  • browser.tabs.list() / browser.tabs.get() worked.
  • Navigation to https://www.zoetispetcare.com/account/rewards worked.
  • Reading body.innerText() worked on the rewards dashboard and the initial invoice instructions page.
  • Clicking through to the invoice submission flow worked.
  • Once on the actual invoice form (/account/rewards/invoice), repeated Chrome-plugin calls timed out until the Node runtime reset.

Calls that timed out included:

  • tab.playwright.locator('input[type="file"]').count()
  • tab.playwright.locator('input').count()
  • tab.playwright.locator('body').innerText(...)
  • tab.playwright.waitForEvent("filechooser", ...) combined with clicking upload text/buttons
  • tab.cua.get_visible_screenshot()
  • tab.dom_cua.get_visible_dom()

The timeout pattern was consistent: the page stayed open in Chrome, but the plugin call hung until the tool reported a timeout and kernel/runtime reset.

Expected behavior

The Chrome plugin should either:

  1. allow normal Playwright/CUA interaction with the upload form, including file chooser upload, or
  2. fail quickly with an actionable error explaining that the page/frame/control cannot be automated.

It should not hang until the runtime resets.

Actual behavior

Chrome-plugin calls against the invoice form repeatedly timed out. This made it impossible to continue the task through @Chrome, despite the browser tab being navigated and logged in successfully.

Environment

  • Codex Desktop on macOS
  • Chrome plugin / Codex Chrome Extension
  • Browser: Google Chrome
  • Site: authenticated Zoetis Petcare Rewards invoice submission form
  • Date observed: 2026-05-07

Notes

This may be related to file upload controls, authenticated pages, page scripts, or the plugin's DOM/CUA bridge on this specific form. The important product issue is that the plugin gets stuck instead of returning a bounded failure.

Activity

  1. added
    bugSomething isn't working
    appIssues related to the Codex desktop app
    tool-callsIssues related to tool calling
    on May 7, 2026
  2. github-actions commented on May 7, 2026

    @github-actions
    Contributor
  3. changed the title [-]Chrome plugin times out on authenticated invoice upload form[/-] [+]Chrome plugin file upload setFiles fails with Not allowed and upload forms can hang[/+] on May 7, 2026
  4. markmdev commented on May 7, 2026

    @markmdev
    Author

    Additional repro detail: this is not limited to the authenticated Zoetis form.

    I created a minimal local page served from http://127.0.0.1 with a plain file input:

    <input id="receipt" name="receipt" type="file">

    Using the Chrome plugin against that simple page:

    const input = tab.playwright.locator('input[type="file"]');
    const chooserPromise = tab.playwright.waitForEvent("filechooser", { timeoutMs: 10000 });
    await input.click();
    const chooser = await chooserPromise;
    await chooser.setFiles(["/absolute/path/to/dummy-upload.txt"]);

    Observed result:

    {"code":-32000,"message":"Not allowed"}
    fileChooser.setFiles failed
    

    So there appear to be two related behaviors:

    1. On a simple local page, Chrome plugin can open the file chooser but chooser.setFiles(...) fails with Not allowed.
    2. On the authenticated invoice upload form, multiple follow-up DOM/CUA/file-upload calls hung until the runtime timed out/reset.

    Environment details from the local checks:

    • macOS
    • Chrome 147.0.7727.138
    • Codex Chrome Extension installed/enabled, version 1.1.4_0
    • Native messaging host manifest exists and matches the expected extension origin
    • Helper scripts succeed when run as node scripts/...
  5. bfeller05 commented on Jul 10, 2026

    @bfeller05

    Confirming the same upload-timeout pattern on Windows and a different authenticated upload surface (observed July 10, 2026).

    Environment

    • Windows
    • Codex Desktop: 26.707.3748.0
    • Codex CLI: 0.144.0
    • Chrome: 150.0.7871.101
    • ChatGPT Chrome Extension: 1.2.27203.26575_0
    • Site: authenticated https://sleek.design/dashboard

    Reproduction

    1. The Chrome plugin connects successfully and claims the already signed-in Sleek dashboard tab.
    2. Initial screenshot and DOM inspection work.
    3. Start waitForEvent("filechooser"), click the page's image-attachment control, and call setFiles(...) with five synthetic/demo-safe PNGs.
    4. The chooser reports success.
    5. The next domSnapshot() call hangs until timeout and resets the browser-control runtime.
    6. Chrome remains visible but covered by a gray locked overlay, preventing normal user interaction.

    The failure persisted after Chrome/Codex/Windows restarts and plugin reinstallation. Local extension and native-host checks passed. No credentials or private/customer data were uploaded.

    This matches the core behavior reported here—normal authenticated navigation followed by upload-page bridge timeout—but also shows the issue on Windows, in newer Codex/extension versions, and with a post-timeout Chrome lock that does not reliably release user control. Related Windows bridge/uninstall report: #21670.

  6. mySebbe commented on Jul 13, 2026

    @mySebbe

    Confirming a second Windows failure mode on an authenticated HTTPS upload form (observed July 13, 2026).

    Environment

    • Windows NT 10.0.26200 x64
    • Codex Desktop: 26.707.8168.0
    • Chrome plugin used for the reproduction: 26.707.30751
    • Chrome: 150.0.7871.115
    • ChatGPT Chrome Extension: 1.2.27203.26575_0

    Reproduction

    1. The Chrome plugin connected, enumerated the existing signed-in tab, claimed it, and read its HTTPS URL and DOM successfully.
    2. The page contained a normal file input and associated label:
      <label for="attachment">Add attachment</label>
      <input id="attachment" type="file">
    3. The documented chooser flow was attempted first against the input and then independently against the visible label:
      const chooserPromise = tab.playwright.waitForEvent("filechooser", { timeoutMs: 10000 });
      await input.click({ force: true }); // the label click was tested separately
      const chooser = await chooserPromise;
    4. Both variants failed with:
      Timed out after 3000ms waiting for file chooser.
      
      The observed 3-second timeout also ignored the requested timeoutMs: 10000.
    5. Chrome's profile state showed file URL access enabled (newAllowFileAccess: true). Extension and native-host health checks passed.
    6. Raw CDP DOM.setFileInputFiles was then rejected by the browser client with:
      This method is not supported through raw CDP. Use tab.playwright.waitForEvent("filechooser") and chooser.setFiles(...) instead.
      

    This leaves no working Chrome-only upload path: the supported chooser event never arrives, while the lower-level file-input command redirects back to the same failing chooser flow. The documented native-picker fallback is also blocked on this Windows setup by the separate browser URL-confidence issue tracked in #25271.

    Expected behavior: the chooser event should fire and permit setFiles(...), or fail with a specific permission/capability error. The configured timeout should also be honored.

    No credentials, private report content, or real user/customer data are included in this reproduction.

  7. mySebbe commented on Jul 13, 2026

    @mySebbe

    Follow-up from the same Windows machine (observed 2026-07-14): I can now distinguish the permission failure from a control-targeting failure, and I have a successful Chrome-only upload path.

    Environment

    • Windows NT 10.0.26200 x64
    • Chrome plugin: 26.707.62119
    • ChatGPT Chrome Extension enabled in the Default profile
    • Extension/native-host health checks pass
    • Allow access to file URLs was already enabled

    Successful isolation test

    A plain local <input type="file"> served from http://127.0.0.1 worked end to end:

    const chooserPromise = tab.playwright.waitForEvent("filechooser", { timeoutMs: 10000 });
    await input.click();
    const chooser = await chooserPromise;
    await chooser.setFiles(["C:/absolute/path/to/test.zip"], { timeoutMs: 15000 });

    The page observed the expected file name, size and MIME type, with no browser warnings/errors. This proves the extension permission and setFiles path were functional in the same Chrome session.

    Authenticated HTTPS form

    The failing form used a visually hidden file input and a visible associated label:

    <label for="attachment">Add attachment</label>
    <input id="attachment" type="file">

    The input was technically display: block but opacity: 0 and approximately 0.09375 × 0.09375 CSS pixels. Waiting for filechooser and clicking the input had previously produced the chooser timeout. Using the visible associated label instead worked:

    const chooserPromise = tab.playwright.waitForEvent("filechooser", { timeoutMs: 10000 });
    await tab.playwright.locator('label[for="attachment"]').click();
    const chooser = await chooserPromise;
    await chooser.setFiles(["C:/absolute/path/to/test.zip"], { timeoutMs: 15000 });

    Afterward the form set C:\\fakepath\\test.zip, marked the field changed, and appended the next empty attachment input. No console warnings/errors were recorded.

    Product implication

    In this failure mode, file-URL permission is not the root cause. The current troubleshooting collapses “chooser never opened” and “setFiles was denied” into the same permission advice. A useful fix would be to:

    1. distinguish chooser-event timeout from setFiles permission/capability failure;
    2. automatically prefer a visible label[for] when the underlying file input is effectively non-interactable;
    3. honor the requested timeout and return a bounded actionable error instead of resetting the runtime.

    No credentials, private report content, target name, or customer data are included here.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    appIssues related to the Codex desktop appbrowserbugSomething isn't workingtool-callsIssues related to tool calling

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions