grafana/k6 · error

attaching new page: %w

Error message

attaching new page: %w

What it means

Thrown by Browser.onAttachedToTarget (internal/js/modules/k6/browser/common/browser.go:337) while handling a CDP Target.attachedToTarget event. After k6 builds the internal Page object for a new target, it registers the page via attachNewPage; if registration fails with anything other than the sentinel errBrowserClosing, the failure is wrapped as 'attaching new page: %w'. In the current implementation attachNewPage only ever returns errBrowserClosing or nil, so this message is a defensive guard against an internal race/invariant failure; when it fires it propagates through initEvents, which panics the VU with 'browser is attaching to target'.

Source

Thrown at internal/js/modules/k6/browser/common/browser.go:337

		b.pagesMu.RUnlock()
	}
	p, err := NewPage(b.vuCtx, session, browserCtx, targetPage.TargetID, opener, isPage, b.logger)
	if err != nil && b.isPageAttachmentErrorIgnorable(ev, session, err) {
		if b.closing.Load() {
			b.logger.Debugf("Browser:onAttachedToTarget", "new page failed; browser is closing: sid:%v", ev.SessionID)
			detachSession(b.browserCtx, session)
		}
		return nil // Ignore this page.
	}
	if err != nil {
		return fmt.Errorf("creating a new %s: %w", targetPage.Type, err)
	}

	// This prevents a race where Close() sets closing and snapshots
	// pages, but a new page is inserted outside that snapshot.
	if err := b.attachNewPage(p, ev); err != nil {
		if !errors.Is(err, errBrowserClosing) {
			return fmt.Errorf("attaching new page: %w", err)
		}

		b.logger.Debugf(
			"Browser:onAttachedToTarget",
			"rejected page attachment; browser is closing: sid:%v tid:%v",
			ev.SessionID, ev.TargetInfo.TargetID,
		)
		if closeErr := p.Close(); closeErr != nil {
			b.logger.Debugf(
				"Browser:onAttachedToTarget",
				"closing rejected page: %v", closeErr,
			)
		}

		detachSession(b.browserCtx, session)

		return nil
	}

View on GitHub (pinned to 93accf6570)

Solutions

  1. Order the script so all page/popup work completes before browser.close(); never close while targets may still attach
  2. Retry the page-creating action once after confirming the browser is still alive (check K6_BROWSER_LOG=debug output)
  3. Capture debug logs (K6_BROWSER_LOG=debug) to get the sid/tid of the rejected target and the wrapped error
  4. Upgrade k6 — attach/closing race handling in the browser module has changed across releases; if it persists, report the debug log to k6

Example fix

// before
page.goto('https://site-with-popups.example') // popups still attaching
browser.close() // races with attach

// after
await page.goto('https://site-with-popups.example')
await page.waitForLoadState()
// popups settled, now close
await browser.close()
Defensive patterns

Strategy: retry

Validate before calling

// avoid closing while targets may attach: sequence the script
// const page = ctx.newPage(); await page.goto(url); await settle(); await browser.close();

Try / catch

try {
  const page = ctx.newPage()
} catch (e) {
  if (/attaching new page|browser is closing/.test(String(e))) {
    // transient shutdown race — only retry if the browser is still usable
    throw e
  }
  throw e
}

Prevention

When it happens

Trigger: A new target (page, popup, iframe) attaches at the exact moment browser.close() runs or the CDP connection is dropping, and the attach fails for a reason other than the closing flag — e.g. closing the browser while a page under test opens popups, or chromium crashing mid-attach.

Common situations: Calling browser.close() (or ending the k6 iteration) while pages/popups are still being created; chromium dying under memory pressure during navigation; races between the browser closing flag and the page map in older k6 browser module versions.

Related errors


AI-assisted analysis of grafana/k6@93accf6570 (2026-08-15). Data as JSON: /api/errors/a9dd6cdf56ba65f9. Report an issue: GitHub.