{"record":{"id":"5db87485e3a49b76","repo":"grafana/k6","slug":"disposing-browser-context-w","errorCode":null,"errorMessage":"disposing browser context: %w","messagePattern":"disposing browser context: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/js/modules/k6/browser/common/browser_context.go","lineNumber":213,"sourceCode":"\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,\n\t\t\"background-sync\":      cdpbrowser.PermissionTypeBackgroundSync,\n\t\t\"ambient-light-sensor\": cdpbrowser.PermissionTypeSensors,\n\t\t\"accelerometer\":        cdpbrowser.PermissionTypeSensors,","sourceCodeStart":195,"sourceCodeEnd":231,"githubUrl":"https://github.com/grafana/k6/blob/93accf6570dcd306ca5e99cc44c393ee3797761b/internal/js/modules/k6/browser/common/browser_context.go#L195-L231","documentation":"BrowserContext.close() calls Target.disposeBrowserContext over CDP via browser.disposeContext (browser_context.go:213); a transport or protocol failure is wrapped as 'disposing browser context: %w'. Typical underlying causes: the context was already disposed (double close), the browser is closing, or the connection is lost.","triggerScenarios":"Calling close() twice on the same context; closing a context after browser.close(); the connection dropping mid-close; two VUs closing the same shared context concurrently.","commonSituations":"Double close from both a helper and teardown; stale context references kept in module-level globals; chromium crashing before teardown runs.","solutions":["Close each context exactly once; null the reference after close()","Ensure context.close() calls all happen before browser.close() in teardown","Read the wrapped error to distinguish double-dispose from dead connection","Use an idempotent close helper that treats 'already disposed' as success"],"exampleFix":"// before\nawait ctx.close()\nawait ctx.close() // second call may throw: disposing browser context\n\n// after\nlet open = true\nasync function closeCtx() { if (open) { await ctx.close(); open = false } }\nawait closeCtx()\nawait closeCtx() // no-op","handlingStrategy":"try-catch","validationCode":"let ctxOpen = true\nasync function closeContext() {\n  if (!ctxOpen) return\n  await ctx.close()\n  ctxOpen = false\n}","typeGuard":null,"tryCatchPattern":"try {\n  await ctx.close()\n} catch (e) {\n  if (/disposing browser context/.test(String(e)) && /invalid browserContextId|already|closed/i.test(String(e))) {\n    ctxOpen = false // treat double-dispose as success\n  } else throw e\n}","preventionTips":["Close each context exactly once; null the reference afterwards","Order teardown: context.close() before browser.close()","Use an idempotent close helper in shared code"],"tags":["browser-context","lifecycle","cdp","double-close"],"backgroundTag":null,"analyzedSha":"93accf6570dcd306ca5e99cc44c393ee3797761b","analyzedAt":"2026-08-15T21:23:27.118Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}