angular/components · error

No keys have been specified.

Error message

No keys have been specified.

What it means

Thrown by SeleniumWebDriverElement.sendKeys when the effective keys array is empty. As with the Protractor variant, sending zero keys would still dispatch a focus event as a side effect, so the library throws getNoKeysSpecifiedError before touching the driver.

Source

Thrown at src/cdk/testing/selenium-webdriver/selenium-web-driver-element.ts:128

      modifiers = first;
      rest = modifiersAndKeys.slice(1);
    } else {
      modifiers = {};
      rest = modifiersAndKeys;
    }

    const modifierKeys = getSeleniumWebDriverModifierKeys(modifiers);
    const keys = rest
      .map(k => (typeof k === 'string' ? k.split('') : [seleniumWebDriverKeyMap[k]]))
      .reduce((arr, k) => arr.concat(k), [])
      // webdriver.Key.chord doesn't work well with geckodriver (mozilla/geckodriver#1502),
      // so avoid it if no modifier keys are required.
      .map(k => (modifierKeys.length > 0 ? webdriver.Key.chord(...modifierKeys, k) : k));

    // Throw an error if no keys have been specified. Calling this function with no
    // keys should not result in a focus event being dispatched unexpectedly.
    if (keys.length === 0) {
      throw getNoKeysSpecifiedError();
    }

    await this.element().sendKeys(...keys);
    await this._stabilize();
  }

  /**
   * Gets the text from the element.
   * @param options Options that affect what text is included.
   */
  async text(options?: TextOptions): Promise<string> {
    await this._stabilize();
    if (options?.exclude) {
      return this._executeScript(_getTextWithExcludedElements, this.element(), options.exclude);
    }
    // We don't go through the WebDriver `getText`, because it excludes text from hidden elements.
    return this._executeScript(
      (element: Element) => (element.textContent || '').trim(),

View on GitHub (pinned to 0411926e7d)

Solutions

  1. Always pass at least one key/character to sendKeys.
  2. Guard the call with if (keys.length) before spreading an array.
  3. Use driver-level Key.chord for modifier-only intentions plus a real key.

Example fix

// before
await element.sendKeys(...keys);
// after
if (!keys.length) throw new Error('keys required');
await element.sendKeys(...keys);
Defensive patterns

Strategy: validation

Validate before calling

if (!keys || keys.length === 0) return;
await element.sendKeys(...keys);

Type guard

const hasKeys = (k: string[] | undefined): k is [string, ...string[]] => Array.isArray(k) && k.length > 0;

Try / catch

try { await element.sendKeys(...keys); } catch (e) { if ((e as Error).message.includes('No keys have been specified')) return; throw e; }

Prevention

When it happens

Trigger: Calling await element.sendKeys() with no arguments, or sendKeys(...keys) with an empty array; also key lists built from conditions that filtered everything out.

Common situations: Generic e2e helpers whose key parameter defaults to []/undefined; tests that pass only modifier key names without an actual key to press.

Related errors


AI-assisted analysis of angular/components@0411926e7d (2026-08-31). Data as JSON: /api/errors/4c1f588a90a05a3f. Report an issue: GitHub.