grafana/k6 · error

cannot do key down: %w

Error message

cannot do key down: %w

What it means

Returned by comboPress (backs Keyboard.Press) when the key-down leg of a combo fails. The keys string is split on '+' and each segment goes through down(); this error wraps the first failing segment, which is either an invalid-key validation error or a CDP dispatch failure. Down-leg failure aborts before any key-up is sent.

Source

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

			key = "Meta"
		} else {
			key = "Control"
		}
	}
	return key
}

func (k *Keyboard) comboPress(keys string, opts KeyboardOptions) error {
	if opts.Delay > 0 {
		if err := wait(k.ctx, opts.Delay); err != nil {
			return err
		}
	}

	kk := split(keys)
	for _, key := range kk {
		if err := k.down(key); err != nil {
			return fmt.Errorf("cannot do key down: %w", err)
		}
	}

	for i := range kk {
		key := kk[len(kk)-i-1]
		if err := k.up(key); err != nil {
			return fmt.Errorf("cannot do key up: %w", err)
		}
	}

	return nil
}

// This splits the string on `+`.
// If `+` on it's own is passed, it will return ["+"].
// If `++` is passed in, it will return ["+", ""].
// If `+++` is passed in, it will return ["+", "+"].
func split(keys string) []string {

View on GitHub (pinned to 93accf6570)

Solutions

  1. Check every combo segment against valid US-layout names ('Control', 'Alt', 'Shift', 'Meta', letters, digits, F-keys)
  2. Watch split() edge cases: a lone '+' is the plus key, but '++' produces an empty invalid segment
  3. Ensure the page stays open for the entire combo
  4. Read the wrapped message to identify which segment failed

Example fix

// before
await page.keyboard.press('Control+Return');
await page.keyboard.press('++');

// after
await page.keyboard.press('Control+Enter');
await page.keyboard.press('+');   // the plus key on its own
Defensive patterns

Strategy: validation

Validate before calling

const parts = combo === '+' ? ['+'] : combo.split('+');
if (parts.some(p => p === '')) throw new Error(`empty segment in combo '${combo}' — see split() rules for '+'`);
if (parts.some(p => !isValidKeyName(p))) throw new Error(`invalid key in combo '${combo}'`);

Type guard

function isValidCombo(c) {
  if (c === '+') return true;
  return c.split('+').every(p => p !== '' && isValidKeyName(p));
}

Try / catch

try {
  await page.keyboard.press(combo);
} catch (e) {
  if (/cannot do key down/.test(e.message) && /not a valid key/.test(e.message)) {
    throw new Error(`combo '${combo}' contains an invalid key — use exact US-layout names`);
  }
  throw e;
}

Prevention

When it happens

Trigger: press('Control+Return') — 'Return' invalid; press('Shift+p') where dispatch fails because the page closed; press('++') where an empty segment from the split is passed to down() and rejected as invalid.

Common situations: Multi-key combos with one misspelled segment; combos issued while navigation tears down the target; misunderstanding of split() edge cases ('++' → ['+', ''], '+++' → ['+', '+']).

Related errors


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