angular/components · error

Element is not associated with a calendar

Error message

Element is not associated with a calendar

What it means

This internal helper resolves a MatCalendarHarness from a datepicker trigger element by reading the calendar's id from the trigger's aria-controls. If the trigger element has no associated calendar id, it throws. This happens when the datepicker popup was never opened or the host isn't actually a connected datepicker trigger.

Source

Thrown at src/material/datepicker/testing/datepicker-trigger-harness-base.ts:97

  // have the ability to close by pressing escape. The backdrop is preferrable, because the
  // escape key has multiple functions inside a range picker (either cancel the current range
  // or close the calendar). Since we don't have access to set the ID on the backdrop in all
  // cases, we set a unique class instead which is the same as the calendar's ID and suffixed
  // with `-backdrop`.
  const backdropSelector = `.${await calendarId}-backdrop`;
  return (await documentLocator.locatorFor(backdropSelector)()).click();
}

/** Gets the test harness for a calendar associated with a particular host. */
export async function getCalendar(
  filter: CalendarHarnessFilters,
  host: Promise<TestElement>,
  documentLocator: LocatorFactory,
): Promise<MatCalendarHarness> {
  const calendarId = await getCalendarId(host);

  if (!calendarId) {
    throw Error(`Element is not associated with a calendar`);
  }

  return documentLocator.locatorFor(
    MatCalendarHarness.with({
      ...filter,
      selector: `#${calendarId}`,
    }),
  )();
}

View on GitHub (pinned to 0411926e7d)

Solutions

  1. Open the calendar first: await (await harness.getTrigger()).openCalendar(), then call getCalendar()
  2. Ensure the input actually has a [matDatePicker] attribute wired to an existing mat-datepicker element
  3. Check that the trigger and datepicker are in the same component and correctly associated

Example fix

// before
const calendar = await trigger.getCalendar();
// after
await trigger.openCalendar();
const calendar = await trigger.getCalendar();
Defensive patterns

Strategy: validation

Validate before calling

await trigger.openCalendar(); // ensure popup is open first
const calendar = await trigger.getCalendar(); // only now is calendarId present

Try / catch

try {
  const calendar = await trigger.getCalendar();
} catch (e) {
  if ((e as Error).message.includes('not associated with a calendar')) {
    await trigger.openCalendar();
    const calendar = await trigger.getCalendar();
  }
}

Prevention

When it happens

Trigger: Calling triggerHarness.getCalendar(filter) while the datepicker popup is closed (aria-controls is absent) or the harness host is not a mat-datepicker-trigger input with a registered calendar.

Common situations: Tests that forgot to call getTrigger('input').then(t => t.openCalendar()) (or dispatch focus+enter) before getCalendar; harness bound to a plain input that has no mat-datepicker attached.

Related errors


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