grafana/k6 · error

waiting for page %s event: %w

Error message

waiting for page %s event: %w

What it means

Page.waitForEvent is the machinery behind page.waitForEvent and internal waits (popup, download, navigation); on any failure path — context canceled, wait timeout, predicate error, or channel error — a deferred wrapper adds 'waiting for page <name> event' around the cause. The error name in the message identifies which event the script was blocked on.

Source

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

		for _, next := range handlers {
			if !yield(next.handler) {
				return
			}
		}
	}
}

// waitForEvent subscribes to the given event and resolves once the predicate
// determines an event should complete the wait or terminate with an error.
func (p *Page) waitForEvent(
	ctx context.Context,
	eventName PageEventName,
	predicate func(PageEvent) (bool, error),
) (_ PageEvent, rerr error) {
	defer func() {
		if rerr != nil {
			rerr = fmt.Errorf("waiting for page %s event: %w", eventName, rerr)
		}
	}()

	type pageEventWaitResult struct {
		event PageEvent
		err   error
	}

	var (
		once   sync.Once
		result = make(chan pageEventWaitResult, 1)
	)
	id, err := p.addEventHandler(eventName, func(event PageEvent) error {
		ok, perr := predicate(event)
		if perr == nil && !ok {
			return nil
		}
		// We don't want to deadlock if another event frequently happens.

View on GitHub (pinned to 93accf6570)

Solutions

  1. Raise the timeout option passed to waitForEvent / waitForNavigation / waitForLoadState
  2. Verify the user flow actually produces the event (manually trigger it once and confirm)
  3. Ensure the page stays open for the whole wait — no concurrent close()
  4. Cancel cleanly by scoping the wait with Promise.race or try/catch around teardown

Example fix

// before
const popup = await page.waitForEvent('popup'); // default timeout may be too short

// after
const popup = await page.waitForEvent('popup', { timeout: 30000 });
Defensive patterns

Strategy: try-catch

Validate before calling

null

Try / catch

try {
  const popup = await page.waitForEvent('popup', { timeout: 30000 });
} catch (e) {
  if (/waiting for page popup event/.test(e.message) && /timeout|timed out/i.test(e.message)) {
    // flow never opened a popup: assert on the trigger, or raise timeout
  } else throw e;
}

Prevention

When it happens

Trigger: page.waitForEvent('popup', {timeout: N}) where no popup opens before the timeout; the page or browser context closes while waiting; the predicate itself errors; the k6 iteration's context is canceled while blocked.

Common situations: Waiting for popups/downloads that never trigger (selector/flow assumptions wrong); timeout option too small under load; waiting on an event after page.close() was called elsewhere.

Related errors


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