Some contrib modules will decorate the path.alias_manager service in order to perform custom checks and operations.

Scenario:
For instance, the fixed_path_alias module provides functionality where you can store URL Aliases in config and it will recreate the info in storage when missing.

When used alongside the menu_export module, which also provides a menu link import/export feature, an error will be produced on attempt to import menu items because early in the process, the menu items do not yet exist.

Additional scenario:

The wse_menu contrib module keeps a separate menu tree per workspace. A menu link created in a workspace is still findable by its link.uri, but its menu tree definition is absent from the Live tree. So when _menu_link_content_update_path_alias() runs in Live, it finds the entity by URI and calls updateDefinition() on a plugin ID that doesn't exist.

Error:

The website encountered an unexpected error. Please try again later.</br></br><em class="placeholder">Drupal\Core\Entity\EntityStorageException</em>: Plugin ID &#039;menu_link_content:3996d408-1d0b-4838-ab65-031ab1cb9826&#039; was not found. in <em class="placeholder">Drupal\Core\Entity\Sql\SqlContentEntityStorage-&gt;save()</em> (line <em class="placeholder">847</em> of <em class="placeholder">core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php</em>). <pre class="backtrace">Drupal\Core\Plugin\Factory\ContainerFactory-&gt;createInstance(&#039;menu_link_content:3996d408-1d0b-4838-ab65-031ab1cb9826&#039;, Array) (Line: 233)
Drupal\Core\Menu\MenuLinkManager-&gt;createInstance(&#039;menu_link_content:3996d408-1d0b-4838-ab65-031ab1cb9826&#039;) (Line: 364)
Drupal\Core\Menu\MenuLinkManager-&gt;updateDefinition(&#039;menu_link_content:3996d408-1d0b-4838-ab65-031ab1cb9826&#039;, Array, ) (Line: 73)
_menu_link_content_update_path_alias(&#039;/manage-content/courses-and-content-library/courses&#039;) (Line: 56)
menu_link_content_path_insert(Array)
call_user_func_array(&#039;menu_link_content_path_insert&#039;, Array) (Line: 403)
Drupal\Core\Extension\ModuleHandler-&gt;invokeAll(&#039;path_insert&#039;, Array) (Line: 119)
Drupal\Core\Path\AliasStorage-&gt;save(&#039;/manage-content/course&#039;, &#039;/manage-content/courses-and-content-library/courses&#039;, &#039;und&#039;) (Line: 209)
Drupal\fixed_path_alias\FixedPathAliasManager-&gt;restoreAlias(Array) (Line: 160)
Drupal\fixed_path_alias\FixedPathAliasManager-&gt;lookupFixedPath(&#039;/manage-content/courses-and-content-library/courses&#039;, &#039;en&#039;, 1) (Line: 106)
Drupal\fixed_path_alias\FixedPathAliasManager-&gt;getPathByAlias(&#039;/manage-content/courses-and-content-library/courses&#039;) (Line: 35)
Drupal\Core\PathProcessor\PathProcessorAlias-&gt;processInbound(&#039;/manage-content/courses-and-content-library/courses&#039;, Object) (Line: 70)
Drupal\Core\PathProcessor\PathProcessorManager-&gt;processInbound(&#039;/manage-content/courses-and-content-library/courses&#039;, Object) (Line: 157)
Drupal\Core\Path\PathValidator-&gt;getPathAttributes(&#039;manage-content/courses-and-content-library/courses&#039;, Object, ) (Line: 122)
Drupal\Core\Path\PathValidator-&gt;getUrl(&#039;manage-content/courses-and-content-library/courses&#039;, ) (Line: 89)
Drupal\Core\Path\PathValidator-&gt;getUrlIfValidWithoutAccessCheck(&#039;manage-content/courses-and-content-library/courses&#039;) (Line: 415)
Drupal\Core\Url::fromInternalUri(Array, Array) (Line: 307)
Drupal\Core\Url::fromUri(&#039;internal:/manage-content/courses-and-content-library/courses&#039;, Array) (Line: 172)
Drupal\link\Plugin\Field\FieldType\LinkItem-&gt;getUrl() (Line: 94)
Drupal\menu_link_content\Entity\MenuLinkContent-&gt;getUrlObject() (Line: 156)
Drupal\menu_link_content\Entity\MenuLinkContent-&gt;getPluginDefinition() (Line: 222)
Drupal\menu_link_content\Entity\MenuLinkContent-&gt;postSave(Object, ) (Line: 526)
Drupal\Core\Entity\EntityStorageBase-&gt;doPostSave(Object, ) (Line: 720)
Drupal\Core\Entity\ContentEntityStorageBase-&gt;doPostSave(Object, ) (Line: 452)
Drupal\Core\Entity\EntityStorageBase-&gt;save(Object) (Line: 838)
Drupal\Core\Entity\Sql\SqlContentEntityStorage-&gt;save(Object) (Line: 394)
Drupal\Core\Entity\EntityBase-&gt;save() (Line: 87)
Drupal\menu_export\Form\MenuImportForm-&gt;submitForm(Array, Object)
call_user_func_array(Array, Array) (Line: 111)
Drupal\Core\Form\FormSubmitter-&gt;executeSubmitHandlers(Array, Object) (Line: 51)
Drupal\Core\Form\FormSubmitter-&gt;doSubmitForm(Array, Object) (Line: 590)
Drupal\Core\Form\FormBuilder-&gt;processForm(&#039;menu_import_form&#039;, Array, Object) (Line: 319)
Drupal\Core\Form\FormBuilder-&gt;buildForm(&#039;menu_import_form&#039;, Object) (Line: 93)
Drupal\Core\Controller\FormController-&gt;getContentResult(Object, Object)
call_user_func_array(Array, Array) (Line: 123)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber-&gt;Drupal\Core\EventSubscriber\{closure}() (Line: 582)
Drupal\Core\Render\Renderer-&gt;executeInRenderContext(Object, Object) (Line: 124)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber-&gt;wrapControllerExecutionInRenderContext(Array, Array) (Line: 97)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber-&gt;Drupal\Core\EventSubscriber\{closure}() (Line: 151)
Symfony\Component\HttpKernel\HttpKernel-&gt;handleRaw(Object, 1) (Line: 68)
Symfony\Component\HttpKernel\HttpKernel-&gt;handle(Object, 1, 1) (Line: 67)
Drupal\simple_oauth\HttpMiddleware\BasicAuthSwap-&gt;handle(Object, 1, 1) (Line: 57)
Drupal\Core\StackMiddleware\Session-&gt;handle(Object, 1, 1) (Line: 47)
Drupal\Core\StackMiddleware\KernelPreHandle-&gt;handle(Object, 1, 1) (Line: 106)
Drupal\page_cache\StackMiddleware\PageCache-&gt;pass(Object, 1, 1) (Line: 85)
Drupal\page_cache\StackMiddleware\PageCache-&gt;handle(Object, 1, 1) (Line: 47)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware-&gt;handle(Object, 1, 1) (Line: 52)
Drupal\Core\StackMiddleware\NegotiationMiddleware-&gt;handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel-&gt;handle(Object, 1, 1) (Line: 693)
Drupal\Core\DrupalKernel-&gt;handle(Object) (Line: 19)
</pre>

Proposed solution:
Add a call to MenuLinkManager::hasDefinition right before call to MenuLinkManager::updateDefinition in _menu_link_content_update_path_alias()

Issue fork drupal-3072557

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

tekNorah created an issue. See original summary.

teknorah’s picture

Status: Active » Needs review
StatusFileSize
new816 bytes

Version: 8.7.5 » 8.7.x-dev

Core issues are now filed against the dev versions where changes will be made. Document the specific release you are using in your issue comment. More information about choosing a version.

Version: 8.7.x-dev » 8.9.x-dev

Drupal 8.8.7 was released on June 3, 2020 and is the final full bugfix release for the Drupal 8.8.x series. Branches prior to 8.8.x are not supported, and Drupal 8.8.x will not receive any further development aside from security fixes. Sites should prepare to update to Drupal 8.9.0 or Drupal 9.0.0 for ongoing support.

Bug reports should be targeted against the 8.9.x-dev branch from now on, and new development or disruptive changes should be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

kristen pol’s picture

Version: 8.9.x-dev » 9.1.x-dev
Issue tags: +Bug Smash Initiative

Patch still applies to 9.1.x.

kristen pol’s picture

Thanks for the issue and patch.

1) The change in the code is clear.

2) Based on issue summary, it's unclear if this can be tested without using custom/contributed code.

3) Kicking off tests in 9.1.x.

kristen pol’s picture

Status: Needs review » Needs work
Issue tags: +Needs tests

Marking needs work for tests.

larowlan’s picture

I think the issue here might be cached plugin definitions

I wonder if fixed_path_alias should be clearing cached definitions in the menu link plugin manager before it does its restoreAlias call?

Version: 9.1.x-dev » 9.2.x-dev

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

Version: 9.2.x-dev » 9.3.x-dev

Drupal 9.2.0-alpha1 will be released the week of May 3, 2021, which means new developments and disruptive changes should now be targeted for the 9.3.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.0-alpha1 was released on May 6, 2022, which means new developments and disruptive changes should now be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.5.x-dev » 10.1.x-dev

Drupal 9.5.0-beta2 and Drupal 10.0.0-beta2 were released on September 29, 2022, which means new developments and disruptive changes should now be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

floown’s picture

Hello.

I just add a node and have this message instead to display the node:

Le site Web a rencontré une erreur inattendue. Veuillez essayer de nouveau plus tard.

Drupal\Component\Plugin\Exception\PluginNotFoundException: Plugin ID 'menu_link_content:ec98d2fd-6c0d-421e-93c6-a5fe28588db4' was not found. in Drupal\Core\Menu\MenuLinkManager->getDefinition() (line 206 of core/lib/Drupal/Core/Menu/MenuLinkManager.php).

Drupal\Core\Plugin\Factory\ContainerFactory->createInstance() (Line: 233)
Drupal\Core\Menu\MenuLinkManager->createInstance() (Line: 44)
Drupal\context\ContextMenuActiveTrail->getActiveLink() (Line: 105)
Drupal\Core\Menu\MenuActiveTrail->doGetActiveTrailIds() (Line: 71)
Drupal\Core\Menu\MenuActiveTrail->resolveCacheMiss() (Line: 149)
Drupal\Core\Cache\CacheCollector->get() (Line: 92)
Drupal\Core\Menu\MenuActiveTrail->getActiveTrailIds() (Line: 236)
Drupal\menu_breadcrumb\MenuBasedBreadcrumbBuilder->applies() (Line: 78)
Drupal\Core\Breadcrumb\BreadcrumbManager->build() (Line: 112)
Drupal\schema_metatag\Plugin\schema_metatag\PropertyType\BreadcrumbList->getItems() (Line: 48)
Drupal\schema_metatag\Plugin\schema_metatag\PropertyType\ItemListElement->outputValue() (Line: 94)
Drupal\schema_metatag\Plugin\schema_metatag\PropertyType\BreadcrumbList->outputValue() (Line: 189)
Drupal\schema_metatag\Plugin\metatag\Tag\SchemaNameBase->outputValue() (Line: 161)
Drupal\schema_metatag\Plugin\metatag\Tag\SchemaNameBase->output() (Line: 621)
Drupal\metatag\MetatagManager->generateRawElements() (Line: 547)
Drupal\metatag\MetatagManager->generateElements() (Line: 520)
metatag_get_tags_from_route() (Line: 277)
_metatag_remove_duplicate_entity_tags() (Line: 219)
metatag_entity_view_alter() (Line: 562)
Drupal\Core\Extension\ModuleHandler->alter() (Line: 305)
Drupal\Core\Entity\EntityViewBuilder->buildMultiple() (Line: 239)
Drupal\Core\Entity\EntityViewBuilder->build()
call_user_func_array() (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback() (Line: 772)
Drupal\Core\Render\Renderer->doCallback() (Line: 363)
Drupal\Core\Render\Renderer->doRender() (Line: 201)
Drupal\Core\Render\Renderer->render() (Line: 241)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 564)
Drupal\Core\Render\Renderer->executeInRenderContext() (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare() (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse() (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray()
call_user_func() (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch() (Line: 164)
Symfony\Component\HttpKernel\HttpKernel->handleRaw() (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle() (Line: 58)
Drupal\Core\StackMiddleware\Session->handle() (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle() (Line: 106)
Drupal\page_cache\StackMiddleware\PageCache->pass() (Line: 85)
Drupal\page_cache\StackMiddleware\PageCache->handle() (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle() (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle() (Line: 23)
Stack\StackedHttpKernel->handle() (Line: 709)
Drupal\Core\DrupalKernel->handle() (Line: 19)

I don't know if it's the same problem. Perhaps a related problem: https://www.drupal.org/project/drupal/issues/3056633#comment-14761566

Regards

Version: 10.1.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 11.x-dev » main

Drupal core is now using the main branch as the primary development branch. New developments and disruptive changes should now be targeted to the main branch.

Read more in the announcement.

amateescu made their first commit to this issue’s fork.

amateescu’s picture

Status: Needs work » Needs review
Issue tags: -Needs tests

I've bumped into the same problem on a project, but from a different angle. In my case, the wse_menu contrib module keeps a separate menu tree per workspace. A menu link created in a workspace is still findable by its link.uri in the Live entity storage (its default revision has the URI), but its menu tree definition is absent from the Live tree. So when _menu_link_content_update_path_alias() runs in Live, it finds the entity by URI and calls updateDefinition() on a plugin ID that doesn't exist.

Guarding this against non-existent definitions is correct regardless of how the divergence arises, the import case in the original report, or per-workspace menu trees here. It also mirrors the existence check core already does in MenuLinkContent::postSave() (getDefinition($id, FALSE) before updateDefinition()), added in #2605684: Routing silently fails in kernel tests.

smustgrave’s picture

Status: Needs review » Needs work
Issue tags: +Needs steps to reproduce

Wonder if we can cleanup the summary some to include maybe core steps to reproduce? Or are we saying this is only triggered by contrib and being defensive?

amateescu’s picture

Issue summary: View changes
Status: Needs work » Needs review
Issue tags: -Needs steps to reproduce

I don't have any steps to reproduce with core alone, but I tried to explain in detail what can happen with a contrib module that provides parallel menu trees. So.. yes, this is about being defensive and consistent with MenuLinkContent::postSave().

smustgrave’s picture

Status: Needs review » Reviewed & tested by the community

That case looks like good defensive step. And thanks for commenting why it's needed.

  • catch committed 17cc005b on main
    fix: #3072557 Plugin ID menu_link_content was not found in...
catch’s picture

Version: main » 11.4.x-dev
Status: Reviewed & tested by the community » Fixed

This looks OK. Not usually a fan of defensiveness but it seems like there are real cases where this is unavoidable.

Committed/pushed to main, 11.x and 11.4.x, thanks!

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.

  • catch committed 4fd5bf98 on 11.4.x
    fix: #3072557 Plugin ID menu_link_content was not found in...

  • catch committed 6cffede3 on 11.x
    fix: #3072557 Plugin ID menu_link_content was not found in...

Status: Fixed » Closed (fixed)

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