{"record":{"id":"449686a8cfdf2582","repo":"grafana/k6","slug":"s-is-not-a-valid-key-for-layout-s","errorCode":null,"errorMessage":"'%s' is not a valid key for layout '%s'","messagePattern":"'(.+?)' is not a valid key for layout '(.+?)'","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/js/modules/k6/browser/common/keyboard.go","lineNumber":144,"sourceCode":"\t\tWithCode(keyDef.Code).\n\t\tWithLocation(keyDef.Location).\n\t\tWithIsKeypad(keyDef.Location == 3).\n\t\tWithText(text).\n\t\tWithUnmodifiedText(text).\n\t\tWithAutoRepeat(autoRepeat)\n\tif err := action.Do(cdp.WithExecutor(k.ctx, k.session)); err != nil {\n\t\treturn fmt.Errorf(\"dispatching key event down: %w\", err)\n\t}\n\n\treturn nil\n}\n\nfunc (k *Keyboard) up(key string) error {\n\tkey = k.platformSpecificResolution(key)\n\n\tkeyInput := keyboardlayout.KeyInput(key)\n\tif _, ok := k.layout.ValidKeys[keyInput]; !ok {\n\t\treturn fmt.Errorf(\"'%s' is not a valid key for layout '%s'\", key, k.layoutName)\n\t}\n\n\tkeyDef := k.keyDefinitionFromKey(keyInput)\n\tk.modifiers &= ^k.modifierBitFromKeyName(keyDef.Key)\n\tk.pressedKeysMu.Lock()\n\tdelete(k.pressedKeys, keyDef.KeyCode)\n\tk.pressedKeysMu.Unlock()\n\n\taction := input.DispatchKeyEvent(input.KeyUp).\n\t\tWithModifiers(input.Modifier(k.modifiers)).\n\t\tWithKey(keyDef.Key).\n\t\tWithWindowsVirtualKeyCode(keyDef.KeyCode).\n\t\tWithCode(keyDef.Code).\n\t\tWithLocation(keyDef.Location)\n\tif err := action.Do(cdp.WithExecutor(k.ctx, k.session)); err != nil {\n\t\treturn fmt.Errorf(\"dispatching key event up: %w\", err)\n\t}\n","sourceCodeStart":126,"sourceCodeEnd":162,"githubUrl":"https://github.com/grafana/k6/blob/93accf6570dcd306ca5e99cc44c393ee3797761b/internal/js/modules/k6/browser/common/keyboard.go#L126-L162","documentation":"Validation error from Keyboard.up(): the key is not present in the active layout's ValidKeys set, rejected locally before any CDP event. Identical condition to the down-path variant but formatted with '%s' quotes instead of %q — the two messages differ only in quoting style.","triggerScenarios":"keyboard.up('Return'), up('escape') (case-sensitive), up('é'); unbalanced pairs where down succeeded with one name and up is called with another (down('Enter'), up('Return')).","commonSituations":"Copy-pasted key names mixing conventions; typos or casing drift between the down and up calls; non-US layouts.","solutions":["Use the exact same valid US-layout key name in up() as in down()","Prefer press() so the pair always matches","Validate the name against the US layout list before calling","For non-layout characters use insertText()"],"exampleFix":"// before\nawait page.keyboard.down('Enter');\nawait page.keyboard.up('Return');\n\n// after\nawait page.keyboard.press('Enter');","handlingStrategy":"validation","validationCode":"if (!isValidKeyName(key)) throw new Error(`unsupported key in up(): ${key}`);\nif (page.isClosed()) throw new Error('page closed before key up');","typeGuard":"function isValidKeyName(k) {\n  const VALID = new Set(['Enter','Backspace','Delete','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 (/is not a valid key for layout/.test(e.message)) {\n    throw new Error(`invalid key name '${key}' in up() — must match the down() name exactly`);\n  }\n  throw e;\n}","preventionTips":["Use one constant for the key name in both down() and up()","Prefer press() to eliminate name drift","Apply the same alias map (Return→Enter) on the up path"],"tags":["browser","keyboard","validation","input","user-error"],"backgroundTag":null,"analyzedSha":"93accf6570dcd306ca5e99cc44c393ee3797761b","analyzedAt":"2026-08-15T21:23:27.118Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}