grafana/k6 · error

key down: %w

Error message

key down: %w

What it means

Returned by Keyboard.press (the private single-key path used by typ()) when its key-down call fails. Distinct from comboPress: this presses exactly one key — wait(opts.Delay) first if set, then down(); the error wraps down()'s invalid-key validation or CDP dispatch failure. The subsequent up() error would surface unwrapped from press().

Source

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

			kk = append(kk, s.String())
			s.Reset()
		} else {
			s.WriteRune(r)
		}
	}
	kk = append(kk, s.String())

	return kk
}

func (k *Keyboard) press(key string, opts KeyboardOptions) error {
	if opts.Delay > 0 {
		if err := wait(k.ctx, opts.Delay); err != nil {
			return err
		}
	}
	if err := k.down(key); err != nil {
		return fmt.Errorf("key down: %w", err)
	}
	return k.up(key)
}

func (k *Keyboard) typ(text string, opts KeyboardOptions) error {
	layout := keyboardlayout.GetKeyboardLayout(k.layoutName)
	for _, c := range text {
		if opts.Delay > 0 {
			if err := wait(k.ctx, opts.Delay); err != nil {
				return err
			}
		}
		keyInput := keyboardlayout.KeyInput(c)
		if _, ok := layout.ValidKeys[keyInput]; ok {
			if err := k.press(string(c), opts); err != nil {
				return fmt.Errorf("pressing key: %w", err)
			}
			continue

View on GitHub (pinned to 93accf6570)

Solutions

  1. Ensure page liveness before typing/pressing (page.isClosed())
  2. On failure, re-acquire the page state and restart the type() from a cleared input
  3. Check the wrapped error to distinguish invalid-key from transport failure
  4. Keep delays modest so fewer presses are in flight when timeouts hit

Example fix

// before
await page.close();
await page.keyboard.press('x');

// after
if (!page.isClosed()) {
  await page.keyboard.press('x');
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (page.isClosed()) throw new Error('page closed before press');
if (!isValidKeyName(key)) throw new Error(`invalid key: ${key}`);

Try / catch

try {
  await page.keyboard.press(key, { delay });
} catch (e) {
  if (/key down/.test(e.message) && /not a valid key/.test(e.message)) throw new Error(`bad key name: ${key}`);
  if (/context|deadline/i.test(e.message)) throw new Error('timeout — lower delay or raise timeout option');
  throw e;
}

Prevention

When it happens

Trigger: typ() pressing a character validated as a layout key but whose dispatch fails (page closed mid-type); direct press('x') on a dead target; delay canceled context surfaces as the bare wait error, not this one.

Common situations: Internal path hit while type() walks a string and the page dies partway; single-key press races with page teardown.

Related errors


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