angular/components · error · Error

Unable to retrieve options for timepicker. Timepicker panel

Error message

Unable to retrieve options for timepicker. Timepicker panel is closed.

What it means

MatTimepickerHarness.getOptions reads the option list from the timepicker's dropdown panel; it refuses to query when the panel is closed. The harness first checks isOpen() and throws 'Timepicker panel is closed.' so consumers get a clear error instead of an empty result.

Source

Thrown at src/material/timepicker/testing/timepicker-harness.ts:44

   */
  static with<T extends MatTimepickerHarness>(
    this: ComponentHarnessConstructor<T>,
    options: TimepickerHarnessFilters = {},
  ): HarnessPredicate<T> {
    return new HarnessPredicate(this, options);
  }

  /** Whether the timepicker is open. */
  async isOpen(): Promise<boolean> {
    const selector = await this._getPanelSelector();
    const panel = await this._documentRootLocator.locatorForOptional(selector)();
    return panel !== null;
  }

  /** Gets the options inside the timepicker panel. */
  async getOptions(filters?: Omit<OptionHarnessFilters, 'ancestor'>): Promise<MatOptionHarness[]> {
    if (!(await this.isOpen())) {
      throw new Error('Unable to retrieve options for timepicker. Timepicker panel is closed.');
    }

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

  /** Selects the first option matching the given filters. */
  async selectOption(filters: OptionHarnessFilters): Promise<void> {
    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();
  }

View on GitHub (pinned to 0411926e7d)

Solutions

  1. Call await harness.open() before getOptions()
  2. Await the harness promise / fixture.whenStable so the panel is rendered
  3. Re-open the panel if a prior selection or close() ended the open state

Example fix

// before
const opts = await timepickerHarness.getOptions(); // throws if closed

// after
await timepickerHarness.open();
const opts = await timepickerHarness.getOptions();
Defensive patterns

Strategy: validation

Validate before calling

if (await timepickerHarness.isOpen()) {
  const opts = await timepickerHarness.getOptions();
} else {
  await timepickerHarness.open();
  const opts = await timepickerHarness.getOptions();
}

Try / catch

try {
  const opts = await timepickerHarness.getOptions();
} catch (e) {
  if (String(e?.message).includes('panel is closed')) {
    await timepickerHarness.open();
    opts = await timepickerHarness.getOptions();
  }
}

Prevention

When it happens

Trigger: Calling harness.getOptions() (or the `options` property) while the timepicker panel is not open — i.e. open() was never called, or it was closed via close()/backdrop click/selection before the call.

Common situations: Tests asserting options immediately without awaiting open(); opening the picker in one step and reading options after an intervening action closed it; forgetting that selecting an option closes the panel.

Related errors


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