{"record":{"id":"9c3708d0021fe39e","repo":"grafana/k6","slug":"updating-extra-http-headers-w-9c3708","errorCode":null,"errorMessage":"updating extra HTTP headers: %w","messagePattern":"updating extra HTTP headers: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/js/modules/k6/browser/common/page.go","lineNumber":840,"sourceCode":"\t\tWidth:  int64(viewportSize.Width),\n\t\tHeight: int64(viewportSize.Height),\n\t}\n\tscreen := Screen{\n\t\tWidth:  int64(viewportSize.Width),\n\t\tHeight: int64(viewportSize.Height),\n\t}\n\treturn p.setEmulatedSize(NewEmulatedSize(viewport, screen))\n}\n\nfunc (p *Page) updateExtraHTTPHeaders() error {\n\tp.logger.Debugf(\"Page:updateExtraHTTPHeaders\", \"sid:%v\", p.sessionID())\n\n\tp.frameSessionsMu.RLock()\n\tdefer p.frameSessionsMu.RUnlock()\n\n\tfor _, fs := range p.frameSessions {\n\t\tif err := fs.updateExtraHTTPHeaders(false); err != nil {\n\t\t\treturn fmt.Errorf(\"updating extra HTTP headers: %w\", err)\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc (p *Page) updateGeolocation() error {\n\tp.logger.Debugf(\"Page:updateGeolocation\", \"sid:%v\", p.sessionID())\n\n\tp.frameSessionsMu.RLock()\n\tdefer p.frameSessionsMu.RUnlock()\n\n\tfor _, fs := range p.frameSessions {\n\t\tp.logger.Debugf(\"Page:updateGeolocation:frameSession\",\n\t\t\t\"sid:%v tid:%v wid:%v\",\n\t\t\tp.sessionID(), fs.targetID, fs.windowID)\n\n\t\tif err := fs.updateGeolocation(false); err != nil {","sourceCodeStart":822,"sourceCodeEnd":858,"githubUrl":"https://github.com/grafana/k6/blob/93accf6570dcd306ca5e99cc44c393ee3797761b/internal/js/modules/k6/browser/common/page.go#L822-L858","documentation":"Page.updateExtraHTTPHeaders fans out Network.setExtraHTTPHeaders to every frame session attached to the page, and this error is returned when any one of those CDP calls fails. It wraps the underlying frame-session failure, so the extra-headers state may be applied inconsistently across frames.","triggerScenarios":"page.setExtraHTTPHeaders({...}) on a page that has iframes (multiple frame sessions), where one frame's session is detached/closed, the page is navigating during the call, or the browser target is gone.","commonSituations":"Setting extra headers right after page.goto while an iframe is still attaching; calling it on a page whose browser context is being torn down; browser crashed mid-test.","solutions":["Call page.setExtraHTTPHeaders before navigation completes or after load state is reached, not during","Verify the page is not closing (page.isClosed()) before the call","Retry the call once after a brief wait if it raced with iframe attachment","Check browser logs for target crashes if it persists"],"exampleFix":"// before\nawait page.goto('https://example.com/');\nawait page.setExtraHTTPHeaders({'X-Test': '1'}); // iframes may still be attaching\n\n// after\nawait page.goto('https://example.com/', { waitUntil: 'networkidle' });\nawait page.setExtraHTTPHeaders({'X-Test': '1'});","handlingStrategy":"try-catch","validationCode":"if (page.isClosed()) throw new Error('cannot set headers on closed page');","typeGuard":null,"tryCatchPattern":"try {\n  await page.setExtraHTTPHeaders(headers);\n} catch (e) {\n  if (/updating extra HTTP headers/.test(e.message)) { await page.waitForTimeout(250); await page.setExtraHTTPHeaders(headers); }\n  else throw e;\n}","preventionTips":["Set extra headers before goto or after networkidle, never mid-attach of iframes","Keep header values as strings; non-string values can push invalid CDP payloads"],"tags":["browser","http-headers","cdp","iframe"],"backgroundTag":null,"analyzedSha":"93accf6570dcd306ca5e99cc44c393ee3797761b","analyzedAt":"2026-08-15T21:23:27.118Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}