microsoft/playwright · error · NonRecoverableDOMError

Unknown key: "${keyString}"

Error message

Unknown key: "${keyString}"

What it means

Thrown by Keyboard._keyDescriptionForString() as a NonRecoverableDOMError when the resolved key string is not found in the US keyboard layout map. The method resolves smart modifiers (ControlOrMeta) first, then looks up the key in usKeyboardLayout. If no entry exists, the key is unknown to Playwright's keyboard emulation. NonRecoverableDOMError means the action will not be retried by the progress system.

Source

Thrown at packages/playwright-core/src/server/input.ts:74

  async apiDown(progress: Progress, key: string) {
    await this._page.instrumentation.onBeforeInputAction(progress, this._page);
    await this.down(progress, key);
  }

  async down(progress: Progress, key: string) {
    const description = this._keyDescriptionForString(key);
    const autoRepeat = this._pressedKeys.has(description.code);
    this._pressedKeys.add(description.code);
    if (kModifiers.includes(description.key as types.KeyboardModifier))
      this._pressedModifiers.add(description.key as types.KeyboardModifier);
    await this._raw.keydown(progress, this._pressedModifiers, key, description, autoRepeat);
  }

  private _keyDescriptionForString(str: string): KeyDescription {
    const keyString = resolveSmartModifierString(str);
    let description = usKeyboardLayout.get(keyString);
    if (!description)
      throw new NonRecoverableDOMError(`Unknown key: "${keyString}"`);
    const shift = this._pressedModifiers.has('Shift');
    description = shift && description.shifted ? description.shifted : description;

    // if any modifiers besides shift are pressed, no text should be sent
    if (this._pressedModifiers.size > 1 || (!this._pressedModifiers.has('Shift') && this._pressedModifiers.size === 1))
      return { ...description, text: '' };
    return description;
  }

  async apiUp(progress: Progress, key: string) {
    await this._page.instrumentation.onBeforeInputAction(progress, this._page);
    await this.up(progress, key);
  }

  async up(progress: Progress, key: string) {
    const description = this._keyDescriptionForString(key);
    if (kModifiers.includes(description.key as types.KeyboardModifier))
      this._pressedModifiers.delete(description.key as types.KeyboardModifier);

View on GitHub (pinned to c8fc3bf8d3)

Solutions

  1. Use a valid key name from the US keyboard layout: 'Enter', 'Tab', 'Escape', 'ArrowUp', 'Control', 'Shift', 'Alt', 'Meta', 'Backspace', 'Delete', 'Home', 'End', 'PageUp', 'PageDown', 'F1'-'F12', or single characters like 'a', '1', '@'.
  2. Use 'ControlOrMeta' as a cross-platform modifier alias (resolves to Meta on macOS, Control elsewhere).
  3. For typing text (not key presses), use page.keyboard.type() or page.fill() instead of individual key presses.
  4. Check the Playwright key names documentation for the complete list of supported keys.

Example fix

// before
await page.keyboard.press('Retern');

// after
await page.keyboard.press('Enter');
Defensive patterns

Strategy: validation

Validate before calling

const VALID_KEYS = new Set(['Enter','Tab','Escape','Backspace','Delete','Insert','Home','End','PageUp','PageDown','ArrowUp','ArrowDown','ArrowLeft','ArrowRight','Control','Shift','Alt','Meta','ControlOrMeta','F1','F2','F3','F4','F5','F6','F7','F8','F9','F10','F11','F12']);
function validateKey(key) {
  if (!VALID_KEYS.has(key) && key.length > 1)
    throw new Error(`Unknown key: ${key}`);
}

Type guard

function isValidKey(key: string): boolean {
  const SPECIAL_KEYS = ['Enter','Tab','Escape','Backspace','Delete','Insert','Home','End','PageUp','PageDown','ArrowUp','ArrowDown','ArrowLeft','ArrowRight','Control','Shift','Alt','Meta','ControlOrMeta'];
  return key.length === 1 || SPECIAL_KEYS.includes(key) || /^F([1-9]|1[0-2])$/.test(key);
}

Prevention

When it happens

Trigger: Calling page.keyboard.press(), keyboard.down(), keyboard.up(), or page.press() with a key name that is not in the US keyboard layout. Examples include typos like 'Retern', unsupported keys like 'Tab' (actually supported but easy to misspell), or keys from non-US layouts that have no US equivalent.

Common situations: Typo in key name (e.g., 'Controll' instead of 'Control'). Using a non-standard key name from documentation or memory. Attempting to press media keys or application keys not in the layout. Passing a multi-character string that is not a recognized key combination.

Related errors


AI-assisted analysis of microsoft/playwright@c8fc3bf8d3 (2026-08-12). Data as JSON: /api/errors/7ec0e22c707385e8. Report an issue: GitHub.