{"record":{"id":"a657aaa724bd4a0f","repo":"grafana/k6","slug":"cannot-do-key-down-w","errorCode":null,"errorMessage":"cannot do key down: %w","messagePattern":"cannot do key down: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/js/modules/k6/browser/common/keyboard.go","lineNumber":270,"sourceCode":"\t\t\tkey = \"Meta\"\n\t\t} else {\n\t\t\tkey = \"Control\"\n\t\t}\n\t}\n\treturn key\n}\n\nfunc (k *Keyboard) comboPress(keys string, opts KeyboardOptions) error {\n\tif opts.Delay > 0 {\n\t\tif err := wait(k.ctx, opts.Delay); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\tkk := split(keys)\n\tfor _, key := range kk {\n\t\tif err := k.down(key); err != nil {\n\t\t\treturn fmt.Errorf(\"cannot do key down: %w\", err)\n\t\t}\n\t}\n\n\tfor i := range kk {\n\t\tkey := kk[len(kk)-i-1]\n\t\tif err := k.up(key); err != nil {\n\t\t\treturn fmt.Errorf(\"cannot do key up: %w\", err)\n\t\t}\n\t}\n\n\treturn nil\n}\n\n// This splits the string on `+`.\n// If `+` on it's own is passed, it will return [\"+\"].\n// If `++` is passed in, it will return [\"+\", \"\"].\n// If `+++` is passed in, it will return [\"+\", \"+\"].\nfunc split(keys string) []string {","sourceCodeStart":252,"sourceCodeEnd":288,"githubUrl":"https://github.com/grafana/k6/blob/93accf6570dcd306ca5e99cc44c393ee3797761b/internal/js/modules/k6/browser/common/keyboard.go#L252-L288","documentation":"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.","triggerScenarios":"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.","commonSituations":"Multi-key combos with one misspelled segment; combos issued while navigation tears down the target; misunderstanding of split() edge cases ('++' → ['+', ''], '+++' → ['+', '+']).","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"],"exampleFix":"// before\nawait page.keyboard.press('Control+Return');\nawait page.keyboard.press('++');\n\n// after\nawait page.keyboard.press('Control+Enter');\nawait page.keyboard.press('+');   // the plus key on its own","handlingStrategy":"validation","validationCode":"const parts = combo === '+' ? ['+'] : combo.split('+');\nif (parts.some(p => p === '')) throw new Error(`empty segment in combo '${combo}' — see split() rules for '+'`);\nif (parts.some(p => !isValidKeyName(p))) throw new Error(`invalid key in combo '${combo}'`);","typeGuard":"function isValidCombo(c) {\n  if (c === '+') return true;\n  return c.split('+').every(p => p !== '' && isValidKeyName(p));\n}","tryCatchPattern":"try {\n  await page.keyboard.press(combo);\n} catch (e) {\n  if (/cannot do key down/.test(e.message) && /not a valid key/.test(e.message)) {\n    throw new Error(`combo '${combo}' contains an invalid key — use exact US-layout names`);\n  }\n  throw e;\n}","preventionTips":["Validate all combo segments up front","Remember '++' contains an empty segment and always fails","Use exact casing for modifiers ('Control', 'Shift', 'Alt', 'Meta')"],"tags":["browser","keyboard","validation","input","combo"],"backgroundTag":null,"analyzedSha":"93accf6570dcd306ca5e99cc44c393ee3797761b","analyzedAt":"2026-08-15T21:23:27.118Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}