Skip to content

[LiveComponent] Fix NoModificationAllowedError when closing the error modal twice - #3501

Merged
Kocal merged 1 commit into
symfony:3.xfrom
Amoifr:fix_ux_3496
Nov 3, 2026
Merged

Kocal merged 1 commit into
symfony:3.xfrom
Amoifr:fix_ux_3496

Conversation

@Amoifr

@Amoifr Amoifr commented Apr 24, 2026

Copy link
Copy Markdown
Contributor
Q A
Bug fix? yes
New feature? no
Deprecations? no
Issues Fix #3496
License MIT

Summary

When the server-error overlay is closed twice in quick succession (double-click, or a click + Escape within the same tick), the second close throws:

NoModificationAllowedError: Failed to set the 'outerHTML' property on 'Element': This element has no parent node.

The root cause (nicely identified by @maarten-mymmo in #3496) is that both close listeners call closeModal(modal) with the same captured reference: the first call detaches the element via modal.outerHTML = '', and the second call then hits the DOM spec rule that outerHTML can't be set on a parent-less element.

Fix

Swap modal.outerHTML = '' for Element.remove(), which is idempotent and safe on detached elements. Same observable effect (element gone), one less footgun.

Test plan

  • 4/4 tests in src/LiveComponent/assets/test/unit/controller/error.test.ts pass (3 existing + 1 new).
  • New regression test closing the error modal twice does not throw documents the invariant.
  • ℹ️ Note on the test: jsdom doesn't enforce the real-browser NoModificationAllowedError on outerHTML for detached elements, so the test can't actively catch a regression to outerHTML. It still guards the "close-twice → clean state, no throw" contract and serves as living documentation.

@github-actions

github-actions Bot commented Apr 27, 2026 •

Copy link
Copy Markdown
Contributor

📊 Packages dist files size difference

Thanks for the PR! Here is the difference in size of the packages dist files between the base branch and the PR.
Please review the changes and make sure they are expected.

FileBefore (Size / Gzip)After (Size / Gzip)
LiveComponent
live_controller.js 92.34 kB / 20.86 kB 92.32 kB0% / 20.85 kB0%

@carsonbot carsonbot added Status: Reviewed Has been reviewed by a maintainer and removed Status: Needs Review Needs to be reviewed labels Nov 3, 2026
Kocal added a commit that referenced this pull request Nov 3, 2026
…injection (nicolas-grekas)

This PR was merged into the 3.x branch.

Discussion
----------

[Pagination] Fix tests with the latest symfony/dependency-injection

| Q              | A
| -------------- | ---
| Bug fix?       | no
| New feature?   | no
| Deprecations?  | no
| Documentation? | no
| Issues         | -
| License        | MIT

symfony/symfony#67757 makes the hidden `.PaginatorInterface $blog` alias point to the paginator service directly, instead of to the `PaginatorInterface $blogPaginator` alias. The test now checks which service this alias resolves to, so that it passes with every supported version of DependencyInjection.

This is what makes the `php (dev, 8.5)` job fail on unrelated PRs, eg #3501.

Commits
-------

10813cc [Pagination] Fix tests with the latest symfony/dependency-injection
… modal twice

Assigning to `outerHTML` throws `NoModificationAllowedError` when the
element has no parent, which happens when the server-error overlay is
closed twice in quick succession (e.g. a double click, or a click +
Escape within the same tick).

Switch to `Element.remove()`, which is idempotent and safe to call on
a detached element. Adds a regression test that documents the
close-twice invariant.

Fixes symfony#3496
@Kocal

Kocal commented Nov 3, 2026

Copy link
Copy Markdown
Member

Thank you @Amoifr.

@Kocal
Kocal merged commit 1cd5c50 into symfony:3.x Nov 3, 2026
37 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Bug Bug Fix LiveComponent Status: Reviewed Has been reviewed by a maintainer

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[LiveComponent] NoModificationAllowedError when closing error modal twice

3 participants