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
- Check every combo segment against valid US-layout names ('Control', 'Alt', 'Shift', 'Meta', letters, digits, F-keys)
- Watch split() edge cases: a lone '+' is the plus key, but '++' produces an empty invalid segment
- Ensure the page stays open for the entire combo
- 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
- Validate all combo segments up front
- Remember '++' contains an empty segment and always fails
- Use exact casing for modifiers ('Control', 'Shift', 'Alt', 'Meta')
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
- sending key down: %w
- sending key up: %w
- pressing key: %w
- %q is not a valid key for layout %q
- '%s' is not a valid key for layout '%s'
AI-assisted analysis of grafana/k6@93accf6570 (2026-08-15).
Data as JSON: /api/errors/a657aaa724bd4a0f.
Report an issue: GitHub.