angular/components · error · Error

Could not find a mat-option matching ${JSON.stringify(filter

Error message

Could not find a mat-option matching ${JSON.stringify(filters)}

What it means

The MatAutocompleteHarness.selectOption test helper focuses the input, queries matching options via getOptions(filters), and throws this error when no rendered mat-option matches the given filter object. It is a harness assertion that the expected option text/selector existed at selection time.

Source

Thrown at src/material/autocomplete/testing/autocomplete-harness.ts:122

      throw new Error(
        'Unable to retrieve option groups for autocomplete. Autocomplete panel is closed.',
      );
    }

    return this._documentRootLocator.locatorForAll(
      MatOptgroupHarness.with({
        ...(filters || {}),
        ancestor: await this._getPanelSelector(),
      } as OptgroupHarnessFilters),
    )();
  }

  /** Selects the first option matching the given filters. */
  async selectOption(filters: OptionHarnessFilters): Promise<void> {
    await this.focus(); // Focus the input to make sure the autocomplete panel is shown.
    const options = await this.getOptions(filters);
    if (!options.length) {
      throw Error(`Could not find a mat-option matching ${JSON.stringify(filters)}`);
    }
    await options[0].click();
  }

  /** Whether the autocomplete is open. */
  async isOpen(): Promise<boolean> {
    const panel = await this._getPanel();
    return !!panel && (await panel.hasClass(`mat-mdc-autocomplete-visible`));
  }

  /** Gets the panel associated with this autocomplete trigger. */
  private async _getPanel(): Promise<TestElement | null> {
    // Technically this is static, but it needs to be in a
    // function, because the autocomplete's panel ID can changed.
    return this._documentRootLocator.locatorForOptional(await this._getPanelSelector())();
  }

  /** Gets the selector that can be used to find the autocomplete trigger's panel. */

View on GitHub (pinned to 0411926e7d)

Solutions

  1. Print available options first (getOptions({}) ) and match exact rendered text.
  2. Await async data: use harness flush/waitForRequestsInFlight-free patterns and ensure the panel options loaded before selectOption.
  3. Normalize filter text to the rendered value (trim, correct locale).
  4. If options load from a server, use fakeAsync/flush or intercept the request so results exist before selection.

Example fix

// before
await harness.selectOption({text: '  New York '}); // whitespace mismatch
// after
await harness.focus();
const opts = await harness.getOptions({});
console.log(opts.map(o => o.getText())); // see actual text
await harness.selectOption({text: 'New York'});
Defensive patterns

Strategy: try-catch

Validate before calling

const options = await harness.getOptions({});
const texts = await Promise.all(options.map(o => o.getText()));
if (!texts.some(t => t.trim() === expectedText)) {
  throw new Error('Available options: ' + texts.join(', '));
}

Try / catch

try {
  await harness.selectOption({text: 'New York'});
} catch (e) {
  if (e instanceof Error && e.message.includes('Could not find a mat-option')) {
    const all = await harness.getOptions({});
    fail('Option missing. Available: ' + JSON.stringify(await Promise.all(all.map(o => o.getText()))));
  } else throw e;
}

Prevention

When it happens

Trigger: Calling harness.selectOption({text: '...'}) when no option's text matches (typo, different casing/whitespace, translated strings), or the panel never rendered options because the input's value/filter didn't produce results.

Common situations: i18n changing option labels after tests were written, options rendered only after async data loads without proper waiting, filter text containing extra whitespace or unicode variants, autocomplete bound to a filtered list that excludes the sought value.

Related errors


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