{"record":{"id":"430824204cfb978c","repo":"grafana/k6","slug":"sending-key-up-w","errorCode":null,"errorMessage":"sending key up: %w","messagePattern":"sending key up: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/js/modules/k6/browser/common/keyboard.go","lineNumber":64,"sourceCode":"\t\tsession:     s,\n\t\tpressedKeys: make(map[int64]struct{}),\n\t\tlayoutName:  \"us\",\n\t\tlayout:      keyboardlayout.GetKeyboardLayout(\"us\"),\n\t}\n}\n\n// Down sends a key down message to a session target.\nfunc (k *Keyboard) Down(key string) error {\n\tif err := k.down(key); err != nil {\n\t\treturn fmt.Errorf(\"sending key down: %w\", err)\n\t}\n\treturn nil\n}\n\n// Up sends a key up message to a session target.\nfunc (k *Keyboard) Up(key string) error {\n\tif err := k.up(key); err != nil {\n\t\treturn fmt.Errorf(\"sending key up: %w\", err)\n\t}\n\treturn nil\n}\n\n// Press sends a key press message to a session target.\n// It delays the action if `Delay` option is specified.\n// A press message consists of successive key down and up messages.\nfunc (k *Keyboard) Press(key string, kbdOpts KeyboardOptions) error {\n\tif err := k.comboPress(key, kbdOpts); err != nil {\n\t\treturn fmt.Errorf(\"pressing key: %w\", err)\n\t}\n\n\treturn nil\n}\n\n// InsertText inserts a text without dispatching key events.\nfunc (k *Keyboard) InsertText(text string) error {\n\tif err := k.insertText(text); err != nil {","sourceCodeStart":46,"sourceCodeEnd":82,"githubUrl":"https://github.com/grafana/k6/blob/93accf6570dcd306ca5e99cc44c393ee3797761b/internal/js/modules/k6/browser/common/keyboard.go#L46-L82","documentation":"Top-level wrapper returned by Keyboard.Up when the private k.up() fails. Like Down, it covers either an invalid key name for the active layout or a failed CDP Input.dispatchKeyEvent(KeyUp) call. Note the modifier bit and pressed-key bookkeeping happen before dispatch, so a failure here can leave keyboard modifier state inconsistent in the session.","triggerScenarios":"keyboard.up('Control') with a key name not in the layout; calling up() after the CDP session died (page closed, browser crashed); unbalanced down/up sequences where the second call races a navigation.","commonSituations":"Calling down() and up() around an await that navigates or closes the page; using localized key names from non-US keyboards.","solutions":["Use valid US-layout key names ('Control', 'Shift', 'Enter')","Keep down()/up() pairs adjacent with no navigation or page close between them","Prefer press('Control+A') which handles the down/up pair atomically via comboPress","Verify the page is open before the call"],"exampleFix":"// before\nawait page.keyboard.down('Control');\nawait page.click('#link');     // may navigate/close\nawait page.keyboard.up('Control');\n\n// after\nawait page.keyboard.press('Control+A');  // atomic down+up","handlingStrategy":"validation","validationCode":"if (page.isClosed()) throw new Error('page closed before key up');\n// validate key name against US-layout list (see isValidKey) before up()","typeGuard":"function isValidKey(k) {\n  const VALID = new Set(['Enter','Backspace','Tab','Escape','ArrowUp','ArrowDown','ArrowLeft','ArrowRight','Home','End','PageUp','PageDown','Control','Shift','Alt','Meta']);\n  return VALID.has(k) || /^[a-zA-Z0-9]$/.test(k) || /^F([1-9]|1[0-2])$/.test(k);\n}","tryCatchPattern":"try {\n  await page.keyboard.up(key);\n} catch (e) {\n  if (/not a valid key/.test(e.message)) throw new Error(`bad key name: ${key}`);\n  if (/dispatching key event up/.test(e.message)) await page.keyboard.press(key); // resync modifiers\n  else throw e;\n}","preventionTips":["Use the same validated key name in down() and up()","Prefer press() for atomic down/up pairs","Never let navigation or page close happen between the pair"],"tags":["browser","keyboard","cdp","input","validation"],"backgroundTag":null,"analyzedSha":"93accf6570dcd306ca5e99cc44c393ee3797761b","analyzedAt":"2026-08-15T21:23:27.118Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}