Skip to content

[LiveComponent] NoModificationAllowedError when closing error modal twice #3496

@maarten-mymmo

Description

@maarten-mymmo

Problem

When a LiveComponent request fails and the error overlay (#live-component-error) is displayed, closing it twice in quick succession throws an uncaught error:
NoModificationAllowedError: Failed to set the 'outerHTML' property on 'Element': This element has no parent node.
Expected: The modal closes cleanly regardless of how many times the close action is triggered.

Actual: The second close attempt throws because the element has already been removed from the DOM.

Steps to reproduce

  1. Set up a LiveComponent that triggers a server error (e.g., a 500 response)
  2. Wait for the full-screen error overlay to appear
  3. Either double-click the overlay quickly, or click it while pressing Escape at the same time
  4. Observe NoModificationAllowedError in the browser console

Details

Version: 2.34.0
Browsers: All
The closeModal function in https://github.com/symfony/ux/blob/2.x/src/LiveComponent/assets/src/Component/index.ts uses modal.outerHTML = '' to remove the element:

const closeModal = (modal: HTMLElement | null) => {                                                                                                                                                                                       
    if (modal) {                                                                                                                                                                                                                          
        modal.outerHTML = '';
    }                                                                                                                                                                                                                                     
    document.body.style.overflow = 'visible';         
};

Both the click and keydown listeners call this function with the same captured modal reference. After the first call removes the element from the DOM, the reference still passes the if (modal) check but setting outerHTML requires the element to have a parent node, so the second call throws.

Suggested fix

Replace modal.outerHTML = '' with modal.remove(), which is idempotent and safe to call on detached elements:

const closeModal = (modal: HTMLElement | null) => {                                                                                                                                                                                       
    if (modal) {                                      
        modal.remove();
    }
    document.body.style.overflow = 'visible';
};

Happy to open a PR if this approach looks good.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions