{"record":{"id":"f70f7c01e7f5511f","repo":"grafana/k6","slug":"key-down-w","errorCode":null,"errorMessage":"key down: %w","messagePattern":"key down: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/js/modules/k6/browser/common/keyboard.go","lineNumber":313,"sourceCode":"\t\t\tkk = append(kk, s.String())\n\t\t\ts.Reset()\n\t\t} else {\n\t\t\ts.WriteRune(r)\n\t\t}\n\t}\n\tkk = append(kk, s.String())\n\n\treturn kk\n}\n\nfunc (k *Keyboard) press(key 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\tif err := k.down(key); err != nil {\n\t\treturn fmt.Errorf(\"key down: %w\", err)\n\t}\n\treturn k.up(key)\n}\n\nfunc (k *Keyboard) typ(text string, opts KeyboardOptions) error {\n\tlayout := keyboardlayout.GetKeyboardLayout(k.layoutName)\n\tfor _, c := range text {\n\t\tif opts.Delay > 0 {\n\t\t\tif err := wait(k.ctx, opts.Delay); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t\tkeyInput := keyboardlayout.KeyInput(c)\n\t\tif _, ok := layout.ValidKeys[keyInput]; ok {\n\t\t\tif err := k.press(string(c), opts); err != nil {\n\t\t\t\treturn fmt.Errorf(\"pressing key: %w\", err)\n\t\t\t}\n\t\t\tcontinue","sourceCodeStart":295,"sourceCodeEnd":331,"githubUrl":"https://github.com/grafana/k6/blob/93accf6570dcd306ca5e99cc44c393ee3797761b/internal/js/modules/k6/browser/common/keyboard.go#L295-L331","documentation":"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().","triggerScenarios":"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.","commonSituations":"Internal path hit while type() walks a string and the page dies partway; single-key press races with page teardown.","solutions":["Ensure page liveness before typing/pressing (page.isClosed())","On failure, re-acquire the page state and restart the type() from a cleared input","Check the wrapped error to distinguish invalid-key from transport failure","Keep delays modest so fewer presses are in flight when timeouts hit"],"exampleFix":"// before\nawait page.close();\nawait page.keyboard.press('x');\n\n// after\nif (!page.isClosed()) {\n  await page.keyboard.press('x');\n}","handlingStrategy":"try-catch","validationCode":"if (page.isClosed()) throw new Error('page closed before press');\nif (!isValidKeyName(key)) throw new Error(`invalid key: ${key}`);","typeGuard":null,"tryCatchPattern":"try {\n  await page.keyboard.press(key, { delay });\n} catch (e) {\n  if (/key down/.test(e.message) && /not a valid key/.test(e.message)) throw new Error(`bad key name: ${key}`);\n  if (/context|deadline/i.test(e.message)) throw new Error('timeout — lower delay or raise timeout option');\n  throw e;\n}","preventionTips":["Validate key names before pressing","Keep delay well under the remaining timeout budget","Stop typing/pressing before closing pages or ending iterations"],"tags":["browser","keyboard","input","cdp"],"backgroundTag":null,"analyzedSha":"93accf6570dcd306ca5e99cc44c393ee3797761b","analyzedAt":"2026-08-15T21:23:27.118Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}