angular/components · error

Attempting to clear an invalid element

Error message

Attempting to clear an invalid element

What it means

UnitTestElement.clear() only supports text input and textarea elements (isTextInput check). Calling clear() on any other element type throws immediately before touching the DOM. This is a deliberate restriction of the harness TestElement contract.

Source

Thrown at src/cdk/testing/testbed/unit-test-element.ts:83

};

/** A `TestElement` implementation for unit tests. */
export class UnitTestElement implements TestElement {
  constructor(
    readonly element: Element,
    private _stabilize: () => Promise<void>,
  ) {}

  /** Blur the element. */
  async blur(): Promise<void> {
    triggerBlur(this.element as HTMLElement);
    await this._stabilize();
  }

  /** Clear the element's input (for input and textarea elements only). */
  async clear(): Promise<void> {
    if (!isTextInput(this.element)) {
      throw Error('Attempting to clear an invalid element');
    }
    clearElement(this.element);
    await this._stabilize();
  }

  /**
   * Click the element at the default location for the current environment. If you need to guarantee
   * the element is clicked at a specific location, consider using `click('center')` or
   * `click(x, y)` instead.
   */
  click(modifiers?: ModifierKeys): Promise<void>;
  /** Click the element at the element's center. */
  click(location: 'center', modifiers?: ModifierKeys): Promise<void>;
  /**
   * Click the element at the specified coordinates relative to the top-left of the element.
   * @param relativeX Coordinate within the element, along the X-axis at which to click.
   * @param relativeY Coordinate within the element, along the Y-axis at which to click.
   * @param modifiers Modifier keys held while clicking

View on GitHub (pinned to 0411926e7d)

Solutions

  1. Only call clear() on input[type=text-like] or textarea elements
  2. For selects, set value via selectOption-style APIs or dispatch change events instead
  3. For contenteditable, set innerText/innerHTML via dispatchEvent or use a custom TestElement method
  4. Check the element type first: (el as any).element instanceof HTMLInputElement or read el.attributes before calling clear

Example fix

// before
await testElement.clear(); // throws for select/contenteditable
// after
const tag = await testElement.matches('input, textarea')
  ? await testElement.getAttribute('type')
  : null;
if (testElementMatchesTextInput) {
  await testElement.clear();
} else {
  await testElement.setProperty('value', '');
  await testElement.dispatchEvent('input');
}
Defensive patterns

Strategy: validation

Validate before calling

const isTextInputEl = async (el: TestElement) => {
  const tag = (await (el as any).element) ? (el as any).element.tagName : await el.matches('input, textarea');
  return /INPUT|TEXTAREA/.test(tag);
};
if (await isTextInputEl(el)) { await el.clear(); }

Type guard

function isTextInputElement(el: HTMLElement): el is HTMLInputElement | HTMLTextAreaElement {
  return el instanceof HTMLTextAreaElement ||
    (el instanceof HTMLInputElement &&
      ['text','search','url','tel','password','email'].includes(el.type));
}

Try / catch

try {
  await el.clear();
} catch (e) {
  if ((e as Error).message.includes('clear an invalid element')) {
    await el.setProperty('value', '');
    await el.dispatchEvent('input');
  } else { throw e; }
}

Prevention

When it happens

Trigger: element.clear() on a div/button/select/contenteditable or an input[type=checkbox|radio|number-with-non-text] that isTextInput rejects; casting a generic TestElement and calling clear without knowing the tag.

Common situations: Trying to clear a select dropdown; clearing a contenteditable rich-text editor; clearing a date input whose type is not classified as a text input; harness code shared across components where the host element differs.

Related errors


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