Problem/Motivation

MenuLinkContent::postSave() calls addDefinition() on every save, so saving a trashed menu link writes a {menu_tree} row again. This happens outside the 'active' trash context, where storage stops filtering trashed entities: workspace publishing, any request on a trash admin route including bulk operations, purging, and core re-parenting the children of a link being removed.

The entity itself stays filtered out, so MenuLinkContent::getEntity() throws a PluginException on any menu walk that checks access. On multilingual sites that is every anonymous page render, because getTitle() and getDescription() resolve the translation through the entity.

Nothing cleans the row up afterwards. MenuTreeStorage::findNoLongerExistingLinks() only purges rows with discovered = 1, and rows written outside a rebuild have discovered = 0, so the row survives every menu rebuild until the link is purged or restored.

Proposed resolution

Decorate plugin.manager.menu.link and refuse addDefinition() and updateDefinition() for links backed by a trashed entity, dropping any row an earlier save left behind. Rebuilds collect their definitions inside the inner manager, out of reach of a decorator, so those are handled by dropping trashed links in hook_menu_links_discovered_alter().

Issue fork trash-3615837

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

amateescu created an issue. See original summary.

amateescu’s picture

Issue summary: View changes
Status: Active » Needs review

  • amateescu committed b0d8a204 on 3.1.x
    fix: #3615837 Trashed menu links are written back to {menu_tree} and...

  • amateescu committed dbf10a41 on 3.x
    fix: #3615837 Trashed menu links are written back to {menu_tree} and...
amateescu’s picture

Status: Needs review » Fixed

Merged into 3.1.x and cherry-picked the relevant parts to 3.x.

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.