{"record":{"id":"6b27d27ede108bb2","repo":"angular/components","slug":"element-is-not-associated-with-a-calendar","errorCode":null,"errorMessage":"Element is not associated with a calendar","messagePattern":"Element is not associated with a calendar","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/material/datepicker/testing/datepicker-trigger-harness-base.ts","lineNumber":97,"sourceCode":"  // have the ability to close by pressing escape. The backdrop is preferrable, because the\n  // escape key has multiple functions inside a range picker (either cancel the current range\n  // or close the calendar). Since we don't have access to set the ID on the backdrop in all\n  // cases, we set a unique class instead which is the same as the calendar's ID and suffixed\n  // with `-backdrop`.\n  const backdropSelector = `.${await calendarId}-backdrop`;\n  return (await documentLocator.locatorFor(backdropSelector)()).click();\n}\n\n/** Gets the test harness for a calendar associated with a particular host. */\nexport async function getCalendar(\n  filter: CalendarHarnessFilters,\n  host: Promise<TestElement>,\n  documentLocator: LocatorFactory,\n): Promise<MatCalendarHarness> {\n  const calendarId = await getCalendarId(host);\n\n  if (!calendarId) {\n    throw Error(`Element is not associated with a calendar`);\n  }\n\n  return documentLocator.locatorFor(\n    MatCalendarHarness.with({\n      ...filter,\n      selector: `#${calendarId}`,\n    }),\n  )();\n}\n","sourceCodeStart":79,"sourceCodeEnd":107,"githubUrl":"https://github.com/angular/components/blob/0411926e7d8ae06b32236ec1048a888cfad5abf2/src/material/datepicker/testing/datepicker-trigger-harness-base.ts#L79-L107","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Open the calendar first: await (await harness.getTrigger()).openCalendar(), then call getCalendar()","Ensure the input actually has a [matDatePicker] attribute wired to an existing mat-datepicker element","Check that the trigger and datepicker are in the same component and correctly associated"],"exampleFix":"// before\nconst calendar = await trigger.getCalendar();\n// after\nawait trigger.openCalendar();\nconst calendar = await trigger.getCalendar();","handlingStrategy":"validation","validationCode":"await trigger.openCalendar(); // ensure popup is open first\nconst calendar = await trigger.getCalendar(); // only now is calendarId present","typeGuard":null,"tryCatchPattern":"try {\n  const calendar = await trigger.getCalendar();\n} catch (e) {\n  if ((e as Error).message.includes('not associated with a calendar')) {\n    await trigger.openCalendar();\n    const calendar = await trigger.getCalendar();\n  }\n}","preventionTips":["Always call openCalendar() before getCalendar() in tests","Verify the input has [matDatePicker] bound to an existing mat-datepicker","Keep harness interactions in order: open, query, act"],"tags":["angular","material","testing","cdk-harness","datepicker"],"backgroundTag":"harness-element-not-found","analyzedSha":"0411926e7d8ae06b32236ec1048a888cfad5abf2","analyzedAt":"2026-08-31T11:58:23.400Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}