[BUG] Claude in Chrome: mouse input and all DOM tools (find/read_page/form_input/javascript_tool) never reach cross-origin iframes (OOPIFs) — embedded Shopify apps undrivable

Status Closed — not planned
Maintainer reply None cached
Activity 1 comment · opened Sep 9, 2026 · closed Sep 9, 2026

Summary

On pages that embed a cross-origin iframe (out-of-process iframe / OOPIF), the Claude in Chrome extension cannot drive the frame: mouse actions never reach it, and every DOM-based tool only sees the top document. Only screenshots and keyboard events cross the boundary.

This makes every embedded Shopify app (the entire Shopify admin app surface, admin.shopify.com/store/<shop>/apps/<handle>) undrivable, since the app is a cross-origin iframe (<iframe name="app-iframe">) inside the admin. The same applies to any admin/SaaS product that hosts third-party UI in an iframe.

Related: #85779 reports the inverse split on Chrome 151 (clicks work, typing fails). On Chrome 152 / extension 1.0.91 I observe the opposite (typing works, clicks fail). Both come from the same cause: the extension only ever talks to the tab-level target.

Environment

  • Claude Code CLI (macOS 15, Darwin 25.5)
  • Claude in Chrome extension 1.0.91
  • Google Chrome 152 (default site isolation)
  • Extension site access: "On all sites" (explicit_host: <all_urls>, withholding_permissions: false)

Repro

  1. Open any Shopify admin with an embedded app installed, e.g. https://admin.shopify.com/store/<shop>/apps/<handle>. The app renders in <iframe name="app-iframe"> on the app's own origin.
  2. computer screenshot → the frame content is visible.
  3. find "buttons inside the app" → returns only admin-shell elements (sidebar links). App content never appears. read_page, get_page_text, form_input, ref-targeted clicks: same.
  4. computer left_click on a button inside the frame (coordinates taken from the screenshot) → tool reports success, nothing happens.
  5. computer scroll at frame coordinates → nothing scrolls.
  6. computer key Tab (x3) → focus moves onto buttons inside the app (focus ring visible in the next screenshot). Keyboard does cross the boundary.

Diagnosis

Instrumented the top document with javascript_tool:

['pointerdown','mousedown','mouseup','click'].forEach(t =>
  document.addEventListener(t, e => console.log('EV', t, e.clientX, e.clientY, e.target.tagName), true));

Then left_click at a point inside the iframe:

EV pointerdown 525 375 IFRAME
EV mousedown   525 375 IFRAME
EV mouseup     525 375 IFRAME
EV click       525 375 IFRAME

The synthetic mouse events are delivered to the parent document with the <iframe> element as target. A real user click at the same point would go straight to the child renderer and the parent would see nothing. So Input.dispatchMouseEvent issued on the tab-level chrome.debugger session is not being routed into the OOPIF.

Coordinate scaling is not the problem: a top-frame probe at screenshot (100, 650) produced clientX/Y = 114, 743, matching the 1512px screenshot vs 1728 CSS px viewport ratio, and top-frame clicks work.

From the extension bundle (assets/mcpPermissions-*.js):

  • Mouse/keyboard: chrome.debugger → Input.dispatchMouseEvent / Input.dispatchKeyEvent / Input.insertText on the tab target. No Target.setAutoAttach, no Target.attachToTarget, no per-session dispatch anywhere in the bundle.
  • read_page / find / form_input / ref clicks: chrome.scripting.executeScript({ target: { tabId } }) with no allFrames / frameIds. The accessibility-tree.js content script is declared with all_frames: true, so window.__generateAccessibilityTree exists in every frame, but it is only ever invoked in the top frame and never descends into iframes (not even same-origin ones).
  • javascript_tool: Runtime.evaluate on the tab session → top frame only.
  • read_console_messages: events from the tab session only; the frame's console is invisible.

Permissions cannot fix it: the extension's own site permission is keyed on the top-level tab URL (admin.shopify.com), the iframe origin is never prompted, and Chrome host access is already <all_urls>.

Expected

The extension should treat OOPIFs like Puppeteer/Playwright do:

  1. Target.setAutoAttach { autoAttach: true, flatten: true, waitForDebuggerOnStart: false } on the root session and track Target.attachedToTarget → sessionId per frame (recursively).
  2. Route Input.* to the session that owns the frame under the pointer (mouse) or the focused frame (keyboard), or let the browser-side router do it consistently.
  3. read_page / find / form_input / ref clicks: run the tree generator with allFrames: true (or per frameIds), merge results with a frame prefix on refs, and translate ref coordinates by the frame's bounding rect in the parent.
  4. javascript_tool: accept an optional frame selector, or at least document that it is top-frame only.
  5. read_console_messages: include attached frame sessions.

Workarounds tried

  • Keyboard-only driving (Tab / Enter / type) with screenshots works but is impractical for complex UIs.
  • Running the app top-level is not an option for Shopify apps: App Bridge (session tokens, resource picker, save bar, nav menu) only works inside the admin frame.

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗