grafana/k6 · error

pressing key: %w

Error message

pressing key: %w

What it means

Wrapper returned by Keyboard.Press when comboPress fails. comboPress first waits opts.Delay (if > 0), then sends key-down for every key in the '+'-separated combo and key-up in reverse order. The error wraps either the initial wait being canceled (context deadline/cancel during delay), an invalid key in the combo, or a failed CDP dispatch.

Source

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

		return fmt.Errorf("sending key down: %w", err)
	}
	return nil
}

// Up sends a key up message to a session target.
func (k *Keyboard) Up(key string) error {
	if err := k.up(key); err != nil {
		return fmt.Errorf("sending key up: %w", err)
	}
	return nil
}

// Press sends a key press message to a session target.
// It delays the action if `Delay` option is specified.
// A press message consists of successive key down and up messages.
func (k *Keyboard) Press(key string, kbdOpts KeyboardOptions) error {
	if err := k.comboPress(key, kbdOpts); err != nil {
		return fmt.Errorf("pressing key: %w", err)
	}

	return nil
}

// InsertText inserts a text without dispatching key events.
func (k *Keyboard) InsertText(text string) error {
	if err := k.insertText(text); err != nil {
		return fmt.Errorf("inserting text: %w", err)
	}
	return nil
}

// Type sends a press message to a session target for each character in text.
// It delays the action if `Delay` option is specified.
//
// It sends an insertText message if a character is not among
// valid characters in the keyboard's layout.

View on GitHub (pinned to 93accf6570)

Solutions

  1. Spell combo segments exactly as US-layout key names: 'Control+C', 'Shift+ArrowDown', 'Enter'
  2. Keep opts.Delay small relative to the test/iteration timeout
  3. Ensure the page is open and focused for the whole combo
  4. Split ambiguous combos: '+' alone is the plus key, '++' means two plus presses — check split() semantics

Example fix

// before
await page.keyboard.press('control+c', { delay: 5000 });

// after
await page.keyboard.press('Control+C');
Defensive patterns

Strategy: validation

Validate before calling

const segments = combo.split('+');
// note: a lone '+' is the plus key; '++' yields an empty invalid segment
if (segments.some(s => s === '' && combo !== '+')) throw new Error(`bad combo: ${combo}`);
if (segments.some(s => !isValidKey(s))) throw new Error(`invalid key in combo: ${combo}`);
if (delayMs * segments.length > maxActionMs) throw new Error('combo delay exceeds timeout');

Type guard

function isValidCombo(combo) {
  if (combo === '+') return true;
  return combo.split('+').every(s => s !== '' && isValidKey(s));
}

Try / catch

try {
  await page.keyboard.press(combo, { delay });
} catch (e) {
  if (/not a valid key/.test(e.message)) throw new Error(`fix key names in combo '${combo}' (US-layout, exact casing)`);
  throw e; // transport/context failure — check page state and retry
}

Prevention

When it happens

Trigger: press('Control+C') where any segment ('Control', 'C') is not a valid layout key; press('Return'); press('Alt+Tab') with a delay long enough that the k6 iteration timeout cancels the context during the wait; page closed mid-combo leaving later dispatches failing.

Common situations: Copy/paste and modifier combos with wrong casing ('control' vs 'Control' — casing matters for layout names); long Delay values colliding with per-iteration timeouts; pressing after browser.close().

Related errors


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