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

  1. Keep down/move/up in one uninterrupted sequence without navigation or long sleeps in between
  2. Check page.isClosed() before mouse.up() and fail fast with a clear message
  3. Re-create the page and restart the whole gesture (not just up) if the session dropped
  4. 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

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


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