{"record":{"id":"9e86ca93c2638319","repo":"grafana/k6","slug":"could-not-find-frame-with-id-s","errorCode":null,"errorMessage":"could not find frame with id %s","messagePattern":"could not find frame with id (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/js/modules/k6/browser/common/frame.go","lineNumber":376,"sourceCode":"\tf.loadingStartedTime = time.Now()\n}\n\nfunc (f *Frame) onLoadingStopped() {\n\tf.log.Debugf(\"Frame:onLoadingStopped\", \"fid:%s furl:%q\", f.ID(), f.URL())\n\n\t// TODO: We should start a timer here and allow the user\n\t//       to set how long to wait until after onLoadingStopped\n\t//       has occurred. The reason we may want a timeout here\n\t//       are for websites where they perform many network\n\t//       requests so it may take a long time for us to see\n\t//       a networkIdle event or we may never see one if the\n\t//       website never stops performing network requests.\n}\n\nfunc (f *Frame) position() (*Position, error) {\n\tframe, ok := f.manager.getFrameByID(cdp.FrameID(f.page.targetID))\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"could not find frame with id %s\", f.page.targetID)\n\t}\n\tif frame == f.page.frameManager.MainFrame() {\n\t\treturn &Position{X: 0, Y: 0}, nil\n\t}\n\telement, err := frame.FrameElement()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tbox, err := element.BoundingBox()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"finding position in frame: %w\", err)\n\t}\n\n\treturn &Position{X: box.X, Y: box.Y}, nil\n}\n\nfunc (f *Frame) removeChildFrame(child *Frame) {","sourceCodeStart":358,"sourceCodeEnd":394,"githubUrl":"https://github.com/grafana/k6/blob/93accf6570dcd306ca5e99cc44c393ee3797761b/internal/js/modules/k6/browser/common/frame.go#L358-L394","documentation":"Frame.position looks up the frame for the page's target ID in the frame manager before computing coordinates (needed for pointer actions and offsets on frame content). If the manager no longer knows the target ID — the page is closing, the target crashed, or the frame tree was rebuilt mid-action — the lookup fails with this error. It is a lifecycle race, not a selector problem.","triggerScenarios":"Pointer/click actions (which need frame position for coordinate math) racing page.close() or a target crash; navigations rebuilding the frame tree while a click is in flight; actions on a page whose renderer process died.","commonSituations":"Cleanup paths where an action is still queued when the iteration ends; high load crashing renderers; closing pages from another async branch while actions run.","solutions":["Ensure no in-flight actions when closing a page; await actions before page.close()","Retry the action after verifying the page is still open","If renderers crash repeatedly (OOM), reduce page weight or increase resources"],"exampleFix":"// before\nawait page.close();\nawait el.click(); // position lookup on a closing page\n\n// after\nawait el.click();\nawait page.close();","handlingStrategy":"validation","validationCode":"if (page.isClosed()) throw new Error('page already closed');\nawait el.click();","typeGuard":null,"tryCatchPattern":"try {\n  await el.click();\n} catch (e) {\n  if (/could not find frame with id/.test(e.message)) {\n    // page/target is gone: skip or restart the scenario\n  } else throw e;\n}","preventionTips":["Await all actions before closing pages","Sequence close() after action promises settle","Guard action entry points with page.isClosed()"],"tags":["browser","frame","lifecycle","race-condition"],"backgroundTag":null,"analyzedSha":"93accf6570dcd306ca5e99cc44c393ee3797761b","analyzedAt":"2026-08-15T21:23:27.118Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}