{"record":{"id":"0baa1b42018dbe32","repo":"grafana/k6","slug":"getting-frame-content-w","errorCode":null,"errorMessage":"getting frame content: %w","messagePattern":"getting frame content: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/js/modules/k6/browser/common/frame.go","lineNumber":782,"sourceCode":"\n// Content returns the HTML content of the frame.\nfunc (f *Frame) Content() (string, error) {\n\tf.log.Debugf(\"Frame:Content\", \"fid:%s furl:%q\", f.ID(), f.URL())\n\n\tjs := `() => {\n\t\tlet content = '';\n\t\tif (document.doctype) {\n\t\t\tcontent = new XMLSerializer().serializeToString(document.doctype);\n\t\t}\n\t\tif (document.documentElement) {\n\t\t\tcontent += document.documentElement.outerHTML;\n\t\t}\n\t\treturn content;\n\t}`\n\n\tv, err := f.Evaluate(js)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"getting frame content: %w\", err)\n\t}\n\ts, ok := v.(string)\n\tif !ok {\n\t\treturn \"\", fmt.Errorf(\"getting frame content: expected string, got %T\", v)\n\t}\n\n\treturn s, nil\n}\n\n// Dblclick double clicks an element matching provided selector.\nfunc (f *Frame) Dblclick(selector string, popts *FrameDblclickOptions) error {\n\tf.log.Debugf(\"Frame:DblClick\", \"fid:%s furl:%q sel:%q\", f.ID(), f.URL(), selector)\n\n\tif err := f.dblclick(selector, popts); err != nil {\n\t\treturn fmt.Errorf(\"double clicking on %q: %w\", selector, err)\n\t}\n\n\tapplySlowMo(f.ctx)","sourceCodeStart":764,"sourceCodeEnd":800,"githubUrl":"https://github.com/grafana/k6/blob/93accf6570dcd306ca5e99cc44c393ee3797761b/internal/js/modules/k6/browser/common/frame.go#L764-L800","documentation":"Frame.Content() serializes the document by evaluating a JS snippet (doctype + documentElement.outerHTML) through f.Evaluate. This error wraps a failure of that evaluation: the execution context was destroyed (navigation started), a CDP protocol error, or the JS throwing in the page.","triggerScenarios":"Calling content() while the page is navigating or immediately after a click that triggers navigation — the main-world execution context is torn down mid-evaluate; the target session is closing; the frame is detached.","commonSituations":"Capturing HTML right after page.goto() or a form submit without waiting; redirect chains; grabbing content in a callback that races navigation; iframe removed from DOM.","solutions":["Wait for the navigation to settle: await page.waitForNavigation() or waitForLoadState('load') before content().","Retry once — the new document's context will serve the next attempt.","Avoid calling content() from racing async paths during navigation."],"exampleFix":"// before\npage.click('#download');\nconst html = page.content(); // mid-navigation -> context destroyed\n\n// after\nawait page.click('#download');\nawait page.waitForLoadState('load');\nconst html = page.content();","handlingStrategy":"retry","validationCode":"await page.waitForLoadState('load');","typeGuard":null,"tryCatchPattern":"let html;\nfor (let i = 0; i < 3; i++) {\n  try { html = page.content(); break; } catch (e) { await page.waitForLoadState('load'); }\n}\nif (!html) throw new Error('content() failed after retries');","preventionTips":["Never call content() concurrently with a navigation trigger.","Always waitForNavigation/waitForLoadState after actions that navigate.","Serialize page interactions within an iteration."],"tags":["browser","content","navigation","execution-context","race-condition"],"backgroundTag":null,"analyzedSha":"93accf6570dcd306ca5e99cc44c393ee3797761b","analyzedAt":"2026-08-15T21:23:27.118Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}