grafana/k6 · error
releasing the mouse button on x:%f y:%f: %w
Error message
releasing the mouse button on x:%f y:%f: %w
What it means
Thrown by Mouse.Up() when the internal m.up() fails. Up() dispatches Input.dispatchMouseEvent(mouseReleased) at the mouse's current coordinates (m.x, m.y). It fails when the DevTools session is gone (page closed, target crashed, browser exited) between the down and the up, or the protocol call is rejected.
Source
Thrown at internal/js/modules/k6/browser/common/mouse.go:100
return nil
}
func (m *Mouse) down(opts *MouseDownUpOptions) error {
m.button = input.MouseButton(opts.Button)
action := input.DispatchMouseEvent(input.MousePressed, m.x, m.y).
WithButton(input.MouseButton(opts.Button)).
WithModifiers(input.Modifier(m.keyboard.modifiers)).
WithClickCount(opts.ClickCount)
if err := action.Do(cdp.WithExecutor(m.ctx, m.session)); err != nil {
return fmt.Errorf("mouse down: %w", err)
}
return nil
}
// Up will trigger a MouseUp event in the browser.
func (m *Mouse) Up(opts *MouseDownUpOptions) error {
if err := m.up(opts); err != nil {
return fmt.Errorf("releasing the mouse button on x:%f y:%f: %w", m.x, m.y, err)
}
return nil
}
func (m *Mouse) up(opts *MouseDownUpOptions) error {
m.button = input.None
action := input.DispatchMouseEvent(input.MouseReleased, m.x, m.y).
WithButton(input.MouseButton(opts.Button)).
WithModifiers(input.Modifier(m.keyboard.modifiers)).
WithClickCount(opts.ClickCount)
if err := action.Do(cdp.WithExecutor(m.ctx, m.session)); err != nil {
return fmt.Errorf("mouse up: %w", err)
}
return nil
}
// Move will trigger a MouseMoved event in the browser.View on GitHub (pinned to 93accf6570)
Solutions
- Keep down/move/up in one uninterrupted sequence without navigation or long sleeps in between
- Check page.isClosed() before mouse.up() and fail fast with a clear message
- Re-create the page and restart the whole gesture (not just up) if the session dropped
- Avoid mousedown handlers that destroy the page mid-gesture
Example fix
// before
await page.mouse.down();
await sleep(10); // page may close here
await page.mouse.up();
// after
await page.mouse.down();
await page.mouse.move(320, 240, { steps: 3 });
await page.mouse.up(); // no gaps that could close the page Defensive patterns
Strategy: try-catch
Validate before calling
if (page.isClosed()) throw new Error('page closed before release');
await page.mouse.up(); Try / catch
try {
await page.mouse.up();
} catch (e) {
if (/target closed|session/i.test(e.message)) {
// gesture unrecoverable on this page; recreate page and restart gesture
throw new Error('session lost between down and up');
}
throw e;
} Prevention
- Finish drag gestures before navigating
- Avoid long sleeps between down and up
- Design app interactions so mousedown does not close the page
When it happens
Trigger: mouse.up() called after the page navigated or closed following mouse.down(); browser/target crash while a press-hold gesture is in flight; dispatch rejected on a dead session.
Common situations: Drag-and-drop simulations where mousedown opens a popup or navigation that invalidates the session; long mouse-hold sleeps exceeding page lifetime; tests resuming gestures on a re-created page (mouse state is per Mouse instance).
Related errors
- pressing the mouse button on x:%f y:%f: %w
- moving the mouse pointer to x:%f y:%f: %w
- clicking on x:%f y:%f: %w
- double clicking on x:%f y:%f: %w
- mouse down: %w
AI-assisted analysis of grafana/k6@93accf6570 (2026-08-15).
Data as JSON: /api/errors/86fd34881b1df3a3.
Report an issue: GitHub.