{"record":{"id":"2bff042345cb6da2","repo":"grafana/k6","slug":"cannot-close-context-as-none-is-active-in-browser","errorCode":null,"errorMessage":"cannot close context as none is active in browser","messagePattern":"cannot close context as none is active in browser","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"internal/js/modules/k6/browser/common/browser.go","lineNumber":691,"sourceCode":"\n\tdeadline := time.After(timeout)\n\tfor len(b.getPages()) > 0 {\n\t\tselect {\n\t\tcase <-deadline:\n\t\t\tb.logger.Debugf(\"Browser:Close\",\n\t\t\t\t\"timed out after %s waiting for %d page(s) to detach; closing anyway\",\n\t\t\t\ttimeout, len(b.getPages()))\n\t\t\treturn\n\t\tcase <-ticker.C:\n\t\t}\n\t}\n}\n\n// CloseContext is a short-cut function to close the current browser's context.\n// If there is no active browser context, it returns an error.\nfunc (b *Browser) CloseContext() error {\n\tif b.context == nil {\n\t\treturn errors.New(\"cannot close context as none is active in browser\")\n\t}\n\treturn b.context.Close()\n}\n\n// Context returns the current browser context or nil.\nfunc (b *Browser) Context() *BrowserContext {\n\treturn b.context\n}\n\n// IsConnected returns whether the WebSocket connection to the browser process\n// is active or not.\nfunc (b *Browser) IsConnected() bool {\n\treturn !b.closing.Load() && b.browserProc.isConnected()\n}\n\n// NewContext creates a new incognito-like browser context.\nfunc (b *Browser) NewContext(opts *BrowserContextOptions) (*BrowserContext, error) {\n\t_, span := TraceAPICall(b.vuCtx, \"\", \"browser.newContext\")","sourceCodeStart":673,"sourceCodeEnd":709,"githubUrl":"https://github.com/grafana/k6/blob/93accf6570dcd306ca5e99cc44c393ee3797761b/internal/js/modules/k6/browser/common/browser.go#L673-L709","documentation":"Browser.CloseContext closes the context k6 tracks as the active one, which is created lazily when the first page is opened. The mapping browser.closeContext() is backed by a promise; if b.context is nil — no page was ever created in this browser, or the context was already closed/cleared — CloseContext returns this error instead of panicking.","triggerScenarios":"Calling await browser.closeContext() before any browser.newPage() in the iteration; calling it twice (the second call finds context already nil); calling it after browser.close() has torn everything down.","commonSituations":"Setup/teardown helpers that unconditionally close the context per iteration even when setup failed early; conditional test flows where page creation was skipped (early exit); reused scripts where a guard was removed.","solutions":["Guard the call: if (browser.context()) await browser.closeContext()","Create at least one page before closing the context in each iteration that closes it","Don't double-close — browser.close() already tears contexts down; drop the manual closeContext in that path"],"exampleFix":"// before\nawait browser.closeContext(); // throws when no context was ever opened\n\n// after\nif (browser.context()) {\n  await browser.closeContext();\n}","handlingStrategy":"type-guard","validationCode":"if (browser.context()) {\n  await browser.closeContext();\n}","typeGuard":"function hasActiveContext(b) {\n  return b.context() !== undefined && b.context() !== null;\n}","tryCatchPattern":"try {\n  await browser.closeContext();\n} catch (e) {\n  if (!e.message.includes('cannot close context as none is active')) throw e;\n  // no context was open — nothing to do\n}","preventionTips":["Pair every closeContext with the page creation that opened the context (same code path)","Let browser.close() handle final teardown instead of manual closeContext at end-of-test","Track whether the iteration actually created a page before running cleanup helpers"],"tags":["browser","closecontext","lifecycle","teardown"],"backgroundTag":null,"analyzedSha":"93accf6570dcd306ca5e99cc44c393ee3797761b","analyzedAt":"2026-08-15T21:23:27.118Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}