{"record":{"id":"e8b8d4e489c4db79","repo":"grafana/k6","slug":"errfatal","errorCode":"ErrFatal","errorMessage":"fatal error","messagePattern":"fatal error","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"internal/js/modules/k6/browser/k6error/internal.go","lineNumber":15,"sourceCode":"// Package k6error contains ErrFatal.\npackage k6error\n\nimport (\n\t\"errors\"\n)\n\n// ErrFatal should be wrapped into an error\n// to signal to the mapping layer that the error\n// is a fatal error and we should abort the whole\n// test run, not just the current iteration. It\n// should be used in cases where if the iteration\n// ran again then there's a 100% chance that it\n// will end up running into the same error.\nvar ErrFatal = errors.New(\"fatal error\")\n","sourceCodeStart":1,"sourceCodeEnd":16,"githubUrl":"https://github.com/grafana/k6/blob/93accf6570dcd306ca5e99cc44c393ee3797761b/internal/js/modules/k6/browser/k6error/internal.go#L1-L16","documentation":"k6error.ErrFatal (k6error/internal.go:8-15) is a sentinel, not a standalone message: browser-module errors wrapped with it — e.g. 'on create page event failed to return a page' (browser_context.go:421) — tell the mapping layer, via panicIfFatalError (browser/helpers.go:20), to abort the whole test run instead of just the current iteration, because the error would recur with certainty on retry.","triggerScenarios":"Structural failures during browser lifecycle operations: page-creation events yielding a non-page object, pages/contexts used after close, or any internal state where re-running the iteration cannot succeed.","commonSituations":"Racing context.close() with pending page creation; reusing pages or contexts across iterations after they were closed; internal k6/browser bugs in specific versions where an event returns an unexpected object.","solutions":["Read the wrapped cause printed alongside 'fatal error' — it names the real failure; fix that root cause","Fix lifecycle handling: don't close the browser context while page creation or events are pending","Create pages fresh per iteration from a long-lived context instead of reusing closed handles","Upgrade k6 to the latest version if the wrapped cause points at an internal browser-module bug"],"exampleFix":"// before\nconst page = await context.newPage();\n// ... later, in another iteration reusing a closed context:\nconst page2 = await context.newPage(); // fatal after close\n\n// after\n// keep the context open for the whole test; create pages per iteration\nexport default async function () {\n  const page = await context.newPage();\n  await page.goto('https://example.com/');\n  await page.close();\n}","handlingStrategy":"try-catch","validationCode":"// Structural preflight: keep the context alive for the whole test\nif (!context || context.isClosed?.()) { context = await browser.newContext(); } // keep open across iterations\nconst page = await context.newPage();","typeGuard":null,"tryCatchPattern":"try {\n  const page = await context.newPage();\n} catch (e) {\n  if (String(e.message).includes('fatal error')) {\n    // abort the run deliberately: report and exit non-zero, do not retry\n    console.error('fatal browser error, aborting:', e.message);\n    throw e;\n  }\n  throw e;\n}","preventionTips":["Never close the browser context while page creation or events are pending","Create pages per iteration from a long-lived context; don't reuse closed handles","Read the wrapped cause next to 'fatal error' — fix the root condition, retrying cannot help","Stay on recent k6 releases for browser-module lifecycle fixes"],"tags":["browser","fatal","lifecycle","test-abort"],"backgroundTag":null,"analyzedSha":"93accf6570dcd306ca5e99cc44c393ee3797761b","analyzedAt":"2026-08-15T21:23:27.118Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}