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
- Raise the timeout option passed to waitForEvent / waitForNavigation / waitForLoadState
- Verify the user flow actually produces the event (manually trigger it once and confirm)
- Ensure the page stays open for the whole wait — no concurrent close()
- 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
- Always pass an explicit timeout sized to the real flow
- Confirm the action that should emit the event is actually performed (click awaited, form submitted)
- Keep the page open for the entire wait; close only after the wait resolves or rejects
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
- browser.on promise rejected: %w
- waiting for element state %q: %w
- checking element is checked %q: %w
- focusing %q: %w
- waiting for %q: %w
AI-assisted analysis of grafana/k6@93accf6570 (2026-08-15).
Data as JSON: /api/errors/cd2127ba7917131d.
Report an issue: GitHub.