{"record":{"id":"4e49dd7feaffdfae","repo":"grafana/k6","slug":"default-browser-context-can-t-be-closed","errorCode":null,"errorMessage":"default browser context can't be closed","messagePattern":"default browser context can't be closed","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/js/modules/k6/browser/common/browser_context.go","lineNumber":210,"sourceCode":"\n// ClearPermissions clears any permission overrides.\nfunc (b *BrowserContext) ClearPermissions() error {\n\tb.logger.Debugf(\"BrowserContext:ClearPermissions\", \"bctxid:%v\", b.id)\n\n\taction := cdpbrowser.ResetPermissions().WithBrowserContextID(b.id)\n\tif err := action.Do(cdp.WithExecutor(b.ctx, b.browser.conn)); err != nil {\n\t\treturn fmt.Errorf(\"clearing permissions: %w\", err)\n\t}\n\n\treturn nil\n}\n\n// Close shuts down the browser context.\nfunc (b *BrowserContext) Close() error {\n\tb.logger.Debugf(\"BrowserContext:Close\", \"bctxid:%v\", b.id)\n\n\tif b.id == \"\" {\n\t\treturn fmt.Errorf(\"default browser context can't be closed\")\n\t}\n\tif err := b.browser.disposeContext(b.id); err != nil {\n\t\treturn fmt.Errorf(\"disposing browser context: %w\", err)\n\t}\n\treturn nil\n}\n\n// GrantPermissions enables the specified permissions, all others will be disabled.\nfunc (b *BrowserContext) GrantPermissions(permissions []string, opts GrantPermissionsOptions) error {\n\tb.logger.Debugf(\"BrowserContext:GrantPermissions\", \"bctxid:%v\", b.id)\n\n\tpermsToProtocol := map[string]cdpbrowser.PermissionType{\n\t\t\"geolocation\":          cdpbrowser.PermissionTypeGeolocation,\n\t\t\"midi\":                 cdpbrowser.PermissionTypeMidi,\n\t\t\"midi-sysex\":           cdpbrowser.PermissionTypeMidiSysex,\n\t\t\"notifications\":        cdpbrowser.PermissionTypeNotifications,\n\t\t\"camera\":               cdpbrowser.PermissionTypeVideoCapture,\n\t\t\"microphone\":           cdpbrowser.PermissionTypeAudioCapture,","sourceCodeStart":192,"sourceCodeEnd":228,"githubUrl":"https://github.com/grafana/k6/blob/01ffac6f245854c1b8adc6a69857c76a15f90022/internal/js/modules/k6/browser/common/browser_context.go#L192-L228","documentation":"BrowserContext.Close() refuses to close Chromium's default browser context, which is represented internally by an empty context ID. The check happens before any CDP call: Target.disposeBrowserContext cannot be applied to the default context, so k6 rejects it locally. Only contexts you created with browser.newContext() can be closed.","triggerScenarios":"Calling close() on the default context — e.g. const ctx = browser.context() (older k6 API) or any handle to the browser's default context — then ctx.close().","commonSituations":"Scripts written for older k6 versions where browser.context() returned the default context; generic 'close everything I touched' cleanup loops that include the default context; porting Playwright code where browser.defaultContext() exists.","solutions":["Create your own context with browser.newContext() and use that instead of the default one","Remove the close() call for the default context — k6 closes it automatically when the browser shuts down","Audit cleanup code so it only closes contexts it created"],"exampleFix":"// before\nconst ctx = browser.context(); // default browser context\nctx.close(); // throws: default browser context can't be closed\n\n// after\nconst ctx = browser.newContext();\nconst page = ctx.newPage();\n// ...\nctx.close(); // user-created context, closes fine","handlingStrategy":"validation","validationCode":"// only close contexts you created with browser.newContext()\nconst ctx = browser.newContext();\n// ... use ctx ...\nif (ctx) ctx.close(); // safe: user-created context","typeGuard":null,"tryCatchPattern":"try {\n  ctx.close();\n} catch (e) {\n  if (String(e.message).includes(\"default browser context can't be closed\")) {\n    // expected when handed the default context: skip and let k6 clean it up\n    console.warn('skipped close of default browser context');\n  } else {\n    throw e;\n  }\n}","preventionTips":["Never call close() on the context from browser.context()/default context","Audit cleanup helpers so they only close contexts created by browser.newContext()","k6 closes the default context automatically at browser shutdown"],"tags":["browser","browser-context","lifecycle","validation"],"backgroundTag":"operation-not-allowed","analyzedSha":"01ffac6f245854c1b8adc6a69857c76a15f90022","analyzedAt":"2026-08-18T03:05:52.393Z","contentChangedAt":"2026-08-18T03:05:52.393Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}