{"record":{"id":"1fc531bb749b9c88","repo":"grafana/k6","slug":"no-frame-found-for-id-s","errorCode":null,"errorMessage":"no frame found for id %s","messagePattern":"no frame found for id (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/js/modules/k6/browser/common/element_handle.go","lineNumber":1164,"sourceCode":"\t\t}\n\t}()\n\n\tif documentHandle.remoteObject.ObjectID == \"\" {\n\t\treturn nil, err\n\t}\n\n\tvar node *cdp.Node\n\taction := dom.DescribeNode().WithObjectID(documentHandle.remoteObject.ObjectID)\n\tif node, err = action.Do(cdp.WithExecutor(h.ctx, h.session)); err != nil {\n\t\treturn nil, fmt.Errorf(\"getting node in frame: %w\", err)\n\t}\n\tif node == nil || node.FrameID == \"\" {\n\t\treturn nil, fmt.Errorf(\"no frame found for node: %w\", err)\n\t}\n\n\tframe, ok := h.frame.manager.getFrameByID(node.FrameID)\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"no frame found for id %s\", node.FrameID)\n\t}\n\n\treturn frame, nil\n}\n\n// Press scrolls element into view and presses the given keys.\nfunc (h *ElementHandle) Press(key string, opts *ElementHandlePressOptions) error {\n\tpress := func(apiCtx context.Context, handle *ElementHandle) (any, error) {\n\t\treturn nil, handle.press(apiCtx, key, KeyboardOptions{})\n\t}\n\tpressAction := h.newAction(\n\t\t[]string{}, press, false, withRetry, opts.NoWaitAfter, opts.Timeout,\n\t)\n\tif _, err := call(h.ctx, pressAction, opts.Timeout); err != nil {\n\t\treturn fmt.Errorf(\"pressing %q on element: %w\", key, err)\n\t}\n\n\tapplySlowMo(h.ctx)","sourceCodeStart":1146,"sourceCodeEnd":1182,"githubUrl":"https://github.com/grafana/k6/blob/93accf6570dcd306ca5e99cc44c393ee3797761b/internal/js/modules/k6/browser/common/element_handle.go#L1146-L1182","documentation":"OwnerFrame() found a FrameID on the node, but the browser's FrameManager has no frame registered with that ID (element_handle.go:1164). The frame was detached or destroyed between the DOM.describeNode call and the manager lookup, or the frame was never tracked (out-of-process iframe crash).","triggerScenarios":"An iframe is removed from the DOM (ads, popups, lazy unmount) right as you interact with an element inside it; frame tree replaced by navigation; OOP iframe process crash.","commonSituations":"Scripts that drill into iframes that get torn down dynamically; SPAs that re-render iframe containers; flaky only when the frame lifecycle races the action.","solutions":["Wait for the frame/element explicitly before acting: page.waitForSelector inside the frame, or frameLocator with an explicit timeout","Retry the whole query once after a short wait — frame detachment is usually transient if the frame is re-created","Assert the iframe still exists (page.frames() / frame url check) before dereferencing elements inside it","If the iframe is legitimately optional, guard the interaction with a existence check"],"exampleFix":"// before\nconst btn = page.locator('iframe#ad >> button');\nbtn.click(); // iframe removed mid-resolution -> no frame found for id ...\n// after\nconst frame = page.frames().find(f => f.url().includes('/widget'));\nif (frame) { await frame.click('button'); }","handlingStrategy":"retry","validationCode":"// Ensure the frame still exists before interacting inside it\nconst frame = page.frames().find(f => f.url().includes('/app/iframe'));\nif (!frame) { /* skip or wait */ }","typeGuard":null,"tryCatchPattern":"try { await frameEl.click(); }\ncatch (e) { if (/no frame found for id/.test(e.message)) { await page.waitForTimeout(500); await page.waitForLoadState(); /* retry once */ } else throw e; }","preventionTips":["Check page.frames() before dereferencing iframe content","Expect iframe teardown in dynamic pages and code the skip path","Wait for elements inside the frame, not just the iframe tag"],"tags":["browser","iframe","frame","race-condition"],"backgroundTag":null,"analyzedSha":"93accf6570dcd306ca5e99cc44c393ee3797761b","analyzedAt":"2026-08-15T21:23:27.118Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}