{"record":{"id":"3d220c695d128cb0","repo":"can1357/oh-my-pi","slug":"tab-ariasnapshot-selector-json-stringify-select","errorCode":null,"errorMessage":"tab.ariaSnapshot: selector ${JSON.stringify(selector)} matched no element","messagePattern":"tab\\.ariaSnapshot: selector (.+?) matched no element","errorType":"exception","errorClass":"ToolError","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/tools/browser/tab-worker.ts","lineNumber":1626,"sourceCode":"\t\t\t\t\t\t\t\t`tab.goto(${JSON.stringify(url)}) timed out after ${budgetBound}ms; pending navigation stopped — retry with a longer tool timeout or waitUntil:\"domcontentloaded\"`,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tthrow err;\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t\tobserve: opts => op(\"tab.observe()\", quickOpMs, sig => this.#collectObservation({ ...opts, signal: sig })),\n\t\t\tariaSnapshot: (selector, opts) =>\n\t\t\t\top(\n\t\t\t\t\tselector ? `tab.ariaSnapshot(${JSON.stringify(selector)})` : \"tab.ariaSnapshot()\",\n\t\t\t\t\tquickOpMs,\n\t\t\t\t\tasync sig => {\n\t\t\t\t\t\tlet root: ElementHandle | null = null;\n\t\t\t\t\t\tif (selector) {\n\t\t\t\t\t\t\troot = (await untilAborted(sig, () =>\n\t\t\t\t\t\t\t\tpage.$(normalizeSelector(selector)),\n\t\t\t\t\t\t\t)) as ElementHandle | null;\n\t\t\t\t\t\t\tif (!root)\n\t\t\t\t\t\t\t\tthrow new ToolError(\n\t\t\t\t\t\t\t\t\t`tab.ariaSnapshot: selector ${JSON.stringify(selector)} matched no element`,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\treturn await untilAborted(sig, () => captureAriaSnapshot(page, root, opts));\n\t\t\t\t\t\t} finally {\n\t\t\t\t\t\t\tawait root?.dispose().catch(() => undefined);\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t),\n\t\t\tscreenshot: opts =>\n\t\t\t\top(describeScreenshot(opts), quickOpMs, sig =>\n\t\t\t\t\tthis.#captureScreenshot(session, output, screenshots, sig, opts),\n\t\t\t\t),\n\t\t\textract: (format = \"markdown\") =>\n\t\t\t\top(`tab.extract(${JSON.stringify(format)})`, quickOpMs, async sig => {\n\t\t\t\t\tconst html = (await untilAborted(sig, () => page.content())) as string;\n\t\t\t\t\tconst result = await extractReadableFromHtml(html, page.url(), format);","sourceCodeStart":1608,"sourceCodeEnd":1644,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/tools/browser/tab-worker.ts#L1608-L1644","documentation":"`tab.ariaSnapshot` accepts an optional selector to scope the accessibility snapshot to a subtree; when `page.$(normalizeSelector(selector))` returns null the selector matched no element and this ToolError is thrown before snapshotting. It prevents silently snapshotting the whole page when a scoping root was requested.","triggerScenarios":"Calling ariaSnapshot with a selector that resolves to nothing: typo, wrong frame/iframe context, element not yet rendered, or shadow-DOM piercing needed but not expressed in the selector.","commonSituations":"Selector written against a different DOM state (pre-render SPA, delayed hydration); CSS selector used where the page uses shadow roots; element inside an iframe not targeted; casing/attribute mismatch.","solutions":["Capture a full-page ariaSnapshot (omit the selector) to inspect actual accessible structure and fix the selector","Wait for the element to appear before snapshotting","Scope the selector to the right frame or use a pierce/shadow-aware selector syntax","Verify the selector with `page.$(selector)` directly to confirm matching"],"exampleFix":"// before\nconst snap = await tab.ariaSnapshot({ selector: '.results-panel' }); // not rendered yet\n// after\nawait tab.wait(() => tab.$('.results-panel'), { timeout: 5000 });\nconst snap = await tab.ariaSnapshot({ selector: '.results-panel' });","handlingStrategy":"validation","validationCode":"if (!(await tab.$(selector))) {\n  throw new Error(`selector ${selector} not present yet`);\n}\nconst snap = await tab.ariaSnapshot({ selector });","typeGuard":null,"tryCatchPattern":"try {\n  return await tab.ariaSnapshot({ selector });\n} catch (err) {\n  if (err instanceof ToolError && err.message.includes('matched no element')) {\n    return await tab.ariaSnapshot(); // full-page fallback\n  }\n  throw err;\n}","preventionTips":["Wait for the element before scoping a snapshot to it","Verify selectors with page.$ before using them as scope roots","Use shadow-piercing or frame-scoped selectors when needed","Capture a full-page snapshot first to discover correct accessible names/structure"],"tags":["selector","aria","accessibility","browser-automation"],"backgroundTag":"selector-no-match","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}