[LiveComponent] NoModificationAllowedError when closing error modal twice

Open Beginner friendly
#3,496 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
1/5
Estimated time
Under an hour
Newbie friendliness
76/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Quiet
Tech stack
typescript
Domain
frontend

Research direction

Start in src/LiveComponent/assets/src/Component/index.ts and inspect closeModal, including the click and keydown listeners that invoke it. Reproduce the error-overlay close action with two rapid triggers, then verify the modal closes without a console error when the element is already detached.

Written by the indexing model from the issue text.

Description

Bug LiveComponent Status: Needs Review

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.

Dominant language
PHP
Stars
1.1k
Forks
431
Avg merge
2d 9h
Merged PRs (30d)
70

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from symfony/ux

All issues in symfony/ux

Similar issues

More PHP issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.