Skip to content

bug(material/select): click during hydration event replay throws "composedPath called during event replay" #33386

@benjam1337

Description

@benjam1337

Is this a regression?

  • Yes, this behavior used to work in the previous version

The previous version in which this bug was not present was

No response

Description

We're seeing errors in production when an app uses SSR with hydration and withEventReplay(). If a user clicks on a mat-select (inside a
mat-form-field) before hydration completes, the click is queued and replayed later, and the replay ends up throwing:

Error: `composedPath` called during event replay.

From what I can tell, Angular core intentionally patches composedPath on replayed events so that it throws, since the composed path is no longer available once browser dispatch is over (see event_dispatcher.ts#prepareEventForReplay).
Meanwhile, the CDK's _getEventTarget helper calls composedPath() unconditionally:

https://github.com/angular/components/blob/main/src/cdk/platform/features/shadow-dom.ts

export function _getEventTarget<T extends EventTarget>(event: Event): T | null {
  return (event.composedPath ? event.composedPath()[0] : event.target) as T | null;
}

The error surfaces through MatSelect.onContainerClick, which calls _getEventTarget(event) to check whether the click landed on an option or the overlay backdrop.

Reproduction

Reproduction repo: https://github.com/benjam1337/repro-cdk-composedpath

It's a vanilla ng new --ssr app (Angular 21.2, Material/CDK 21.2.2, live SSR via RenderMode.Server). The only tweaks, detailed in the README, are:

  • a mat-form-field + mat-select in the root component;
  • a 20-second artificial delay before client bootstrap in main.ts, to make
    the pre-hydration click window deterministic (in a real app this window
    exists on slow devices/networks).

Steps to reproduce:

  1. npm install && npm run build
  2. node dist/repro-cdk-composedpath/server/server.mjs and open http://localhost:4000 with the DevTools console open
  3. Click on the "Country" select within 20 seconds of page load (before hydration completes)
  4. Once hydration completes and the click is replayed, the error is thrown

Clicking after hydration works fine, only clicks queued during the pre-hydration window trigger the error.

(I went with a repo rather than StackBlitz because the repro needs the real SSR server + hydration flow, which I couldn't get working reliably there.)

Expected Behavior

The replayed click is handled gracefully and the select opens (or at least fails silently), without an error reaching the application ErrorHandler.

Actual Behavior

Error: `composedPath` called during event replay. is thrown, the replayed click appears to be lost, and the error propagates to the application ErrorHandler (so it gets reported to our error tracking for every affected user).

Environment

  • Angular: 21.2.6 (reproduced with 21.2.17 as well)
  • CDK/Material: 21.2.2
  • Browser(s): observed on Samsung Internet 30 (Android), Chrome Mobile, and others. Seems timing-dependent rather than browser-specific; reproduced locally in Chromium
  • Operating System: Android, iOS, Windows, macOS (production traffic); repro on macOS

Metadata

Metadata

Assignees

Labels

P3An issue that is relevant to core functions, but does not impede progress. Important, but not urgentarea: cdk/platformarea: material/selectgemini-triagedLabel noting that an issue has been triaged by gemini

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions