Problem/Motivation

Upgrading to latest version 3.0.4 is breaking menus in our multilanguage site. Problem stems from the latest update hook taxonomy_menu_ui_update_9001 where update hook is renaming menu bundle to be the same as menu name. In our case bundle for all our menus is always "menu_link_content" since we are using core module with the same name which will preset the bundle name as "menu_link_content": https://git.drupalcode.org/project/drupal/-/blob/10.4.x/core/modules/men...

Steps to reproduce

- Enable menu_link_content module and taxonomy_menu_ui (3.0.3 before latest change introduced)
- Create a new menu and add a menu link
- Update module taxonomy_menu_ui to the latest 3.0.4

Proposed resolution

I don't fully know the background and the reason for this change. Let me know if more info or help is needed.

Remaining tasks

User interface changes

API changes

Data model changes

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

borutpiletic created an issue. See original summary.

lobodakyrylo’s picture

Some time ago, Drupal Core added a bundle field to content menu items, and by default, it's always the same as the menu name. Unfortunately, no one noticed that, and the module created menu items without a bundle, and the core changed the bundle with the "menu_link_content" which is the entity name. Because of that, you can't translate menu items. If your menu is "main_menu", and you set translation for that, the core identifies menu items you created via this module as "menu_link_content" and this bundle doesn't have translation settings. To solve this, all the bundles should be the same as the menu names. This update did this.

I couldn't reproduce this issue you experienced, please provide more information about your menu names, menu items, and maybe screenshots what happened after update.

alexander tallqvist’s picture

We are experiencing the same issue on our multilingual Drupal site running Drupal 10.3.11.

Default language: Finnish (FI)

Translated languages: English (EN) and Swedish (SV)

Issue Details

After applying the latest version of taxonomy_menu_ui and running database updates, we encountered the following problems:

1. Fatal Error When Editing or Unpublishing Translated Nodes

Attempting to edit or unpublish a translated version of a node (SV or EN) results in a fatal error when saving:

InvalidArgumentException: A translation already exists for the specified language (sv). in Drupal\Core\Entity\ContentEntityBase->onChange() (line 840 of /app/web/core/lib/Drupal/Core/Entity/ContentEntityBase.php).
#0 /app/web/core/lib/Drupal/Core/Entity/Plugin/DataType/EntityAdapter.php(140): Drupal\Core\Entity\ContentEntityBase->onChange('langcode')
#1 /app/web/core/lib/Drupal/Core/TypedData/Plugin/DataType/ItemList.php(82): Drupal\Core\Entity\Plugin\DataType\EntityAdapter->onChange('langcode')
#2 /app/web/core/lib/Drupal/Core/Field/FieldItemList.php(107): Drupal\Core\TypedData\Plugin\DataType\ItemList->setValue(Array, true)
#3 /app/web/core/lib/Drupal/Core/Entity/ContentEntityBase.php(657): Drupal\Core\Field\FieldItemList->setValue(Array, true)
#4 /app/web/core/modules/menu_ui/menu_ui.module(109): Drupal\Core\Entity\ContentEntityBase->set('langcode', 'sv')
#5 /app/web/core/modules/menu_ui/menu_ui.module(349): _menu_ui_node_save(Object(Drupal\node\Entity\Node), Array)
#6 [internal function]: menu_ui_form_node_form_submit(Array, Object(Drupal\Core\Form\FormState))
#7 /app/web/core/lib/Drupal/Core/Form/FormSubmitter.php(129): call_user_func_array('menu_ui_form_no...', Array)
#8 /app/web/core/lib/Drupal/Core/Form/FormSubmitter.php(67): Drupal\Core\Form\FormSubmitter->executeSubmitHandlers(Array, Object(Drupal\Core\Form\FormState))
#9 /app/web/core/lib/Drupal/Core/Form/FormBuilder.php(597): Drupal\Core\Form\FormSubmitter->doSubmitForm(Array, Object(Drupal\Core\Form\FormState))
#10 /app/web/core/lib/Drupal/Core/Form/FormBuilder.php(326): Drupal\Core\Form\FormBuilder->processForm('node_page_edit_...', Array, Object(Drupal\Core\Form\FormState))
#11 /app/web/core/lib/Drupal/Core/Controller/FormController.php(73): Drupal\Core\Form\FormBuilder->buildForm(Object(Drupal\node\NodeForm), Object(Drupal\Core\Form\FormState))
#12 [internal function]: Drupal\Core\Controller\FormController->getContentResult(Object(Symfony\Component\HttpFoundation\Request), Object(Drupal\Core\Routing\RouteMatch))
#13 /app/web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(123): call_user_func_array(Array, Array)
#14 /app/web/core/lib/Drupal/Core/Render/Renderer.php(638): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}()
#15 /app/web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(121): Drupal\Core\Render\Renderer->executeInRenderContext(Object(Drupal\Core\Render\RenderContext), Object(Closure))
#16 /app/web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(97): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext(Array, Array)
#17 /app/vendor/symfony/http-kernel/HttpKernel.php(181): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}()
#18 /app/vendor/symfony/http-kernel/HttpKernel.php(76): Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object(Symfony\Component\HttpFoundation\Request), 1)
#19 /app/web/modules/contrib/force_password_change/src/Service/ForcePasswordChangeRedirectMiddleware.php(43): Symfony\Component\HttpKernel\HttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#20 /app/web/core/lib/Drupal/Core/StackMiddleware/Session.php(53): Drupal\force_password_change\Service\ForcePasswordChangeRedirectMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#21 /app/web/core/lib/Drupal/Core/StackMiddleware/KernelPreHandle.php(48): Drupal\Core\StackMiddleware\Session->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#22 /app/web/core/lib/Drupal/Core/StackMiddleware/ContentLength.php(28): Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#23 /app/web/core/modules/page_cache/src/StackMiddleware/PageCache.php(106): Drupal\Core\StackMiddleware\ContentLength->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#24 /app/web/core/modules/page_cache/src/StackMiddleware/PageCache.php(85): Drupal\page_cache\StackMiddleware\PageCache->pass(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#25 /app/web/core/lib/Drupal/Core/StackMiddleware/ReverseProxyMiddleware.php(48): Drupal\page_cache\StackMiddleware\PageCache->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#26 /app/web/core/lib/Drupal/Core/StackMiddleware/NegotiationMiddleware.php(51): Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#27 /app/web/core/lib/Drupal/Core/StackMiddleware/AjaxPageState.php(36): Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#28 /app/web/core/lib/Drupal/Core/StackMiddleware/StackedHttpKernel.php(51): Drupal\Core\StackMiddleware\AjaxPageState->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#29 /app/web/core/lib/Drupal/Core/DrupalKernel.php(741): Drupal\Core\StackMiddleware\StackedHttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#30 /app/web/index.php(19): Drupal\Core\DrupalKernel->handle(Object(Symfony\Component\HttpFoundation\Request))
#31 {main}

2. Menu Link Text Overwritten After Fatal Error

After triggering the fatal error, the menu link text of the original (FI) translation is overwritten with the text from the edited translation.

Example:

Original FI node menu link text: "Hei maailma!"
Translated EN node menu link text: "Hello world!"
If we attempt to unpublish the EN version, the fatal error occurs.
After this, the FI node's menu text changes to "Hello world!" instead of staying as "Hei maailma!".

Potential fix

Adding the following update hook to a module and running database updates seems to fix the issue for use:

function hook_update(): void {
  $entities = \Drupal::entityTypeManager()
    ->getStorage('menu_link_content')
    ->loadMultiple();

  foreach ($entities as $entity) {
    if ($entity->get('bundle')->value !== 'menu_link_content') {
      $entity->set('bundle', 'menu_link_content');
      $entity->save();
    }
  }
}
lobodakyrylo’s picture

It happened because the menu name was previously used to get to the menu to which the link belonged. Later, the bundle field was defined for this purpose, and the menu name field is a rudiment field now. We didn't notice it in time, so you have the bundle field empty for menu items that were created by this module or by other modules. So if you have several menus, for example, header, and footer, then all menu items for the header will have bundle and menu name field as "header" and "footer" for footer.

For me, the menu_link_content bundle is incorrect since it doesn't belong to any menu. I'm curious how you created translation for menus that don't have a bundle since you can't create a translation configuration for that.

mydot’s picture

For me the same error. After Taxonomy menu UI module update i can not update existing node translations with menu link. When i try to modify the menu item from the menu configuration i get error:

Drupal\Component\Plugin\Exception\PluginNotFoundException: The "entity:menu_link_content:main" plugin does not exist. Valid plugin IDs for Drupal\Core\TypedData\TypedDataManager are: ... entity_revision:menu_link_content, entity_revision:menu_link_content:menu_link_content, ... entity:menu_link_content, entity:menu_link_content:menu_link_content, ... in Drupal\Core\Plugin\DefaultPluginManager->doGetDefinition() (line 53 of /core/lib/Drupal/Component/Plugin/Discovery/DiscoveryTrait.php).

i use Taxonomy menu UI 3.0.5 with Drupal 11.1.3

lobodakyrylo’s picture

Priority: Normal » Major

It seems that the menu module sometimes uses the menu name for bundle and sometimes the menu_link_content value. I'm not sure what's going on there, but it looks like a major issue for now. I can't reproduce it on my side since all my websites that use this module had a smooth transition to the new version.

It'd be good if someone gave me the configuration files and composer.json that you use.

jaroslav červený’s picture

StatusFileSize
new729 bytes

I tested the hook update and it helped.

dewalt’s picture

I have the same issue with error on menu item edit:

Drupal\Component\Plugin\Exception\PluginNotFoundException: The "entity:menu_link_content:main" plugin does not exist.

Drupal\Component\Plugin\Exception\PluginNotFoundException: The "entity:menu_link_content:footer" plugin does not exist.

Thanks Jaroslav, the patch is working for existing menu items. I've extended it to avoid the issue with new created ones. Bundle isn't needed to be specified due https://www.drupal.org/project/drupal/issues/2350915.

Kyrylo, I see you've tried to add translations support here - https://git.drupalcode.org/project/taxonomy_menu_ui/-/commit/ae60c128775.... I have no idea how setting the bundle field should help, please look "_menu_ui_node_save()" for example. The main idea is:
- If link exist and it is a translation of existing link - create it with $entity->addTranslation($term->language()->getId(), $data);
- If link is new, please ensure that the link langcode matches with term langcode: $entity->set('langcode', $term->language()->getId());

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

shivam_tiwari’s picture

Status: Active » Needs review

I faced same issue after updating taxonomy_menu_ui module to the latest version. I checked patches added here. #8 patch fixed issue for me. I created MR so we can run test and merge this update to the latest versions.
Thanks

banoodle’s picture

Status: Needs review » Reviewed & tested by the community

Confirming the mr fixes the problem introduced by update 9001.

The site I experienced this problem on uses translation and we didn't have any blank bundles in the menu_link_content_data table and everything was working fine until we attempted to upgrade from 3.0.3 to 3.0.5 of this module.

Update 9001 made the translation settings and a custom field we added on menu links vanish from the UI and front-end.

lobodakyrylo’s picture

Status: Reviewed & tested by the community » Needs work

Merge request #6 is completely wrong even though it solves your problem. The bundle field should contain the same as menu_name because if you enable translations for the menu, you will not be able to translate menu items. Translation settings correspond to the bundle name and if they do not fit, then by default the translation is disabled. Let's say you have a menu "Header", then you want to translate it. You go to settings and enable translation for them. But if you try to translate its menu items, their bundle will be menu_link_content not header and Drupal will not allow you to translate them. Read comment #4.

I couldn't reproduce this when Drupal creates a menu item with the menu_link_content bundle. It may happen in the previous versions of Drupal when it added the bundle field but the current structure requires to have bundle the same as menu_name. The menu_item field still exists and as I understand it's a rudiment and will be deleted in the future.

If you can reproduce the menu_link_content bundle from a fresh install, then tell me how to do it.

robertom’s picture

StatusFileSize
new576 bytes

Hi @lobodakyrylo, what version of drupal are you using?

I just installed this module, but with Drupal 10.4.6 I can make it work correctly (with translations) only by using the attached patch (it is the same one present in the MR, but without taxonomy_menu_ui_update_9002() )

To see how Drupal behaves by default I performed the following steps:

  • Installed Drupal 10.4.6
  • Enabled "Custom menu links"
  • Enabled "Content translation"
  • Enabled two languages: "Italian" and "Spanish"
  • I went to /admin/config/regional/content-language
    • Enabled "Custom menu link" in "Custom language settings"
    • Enabled "Menu link title" and "Changed" in "Custom menu link"
  • Created a new "Test" menu
  • Created a link item inside the "Test" menu called "Test en" with a link to an article content translated in en, es, it
  • Translated the link "Test en" into Italian language by changing the title with "Test it"
  • Translated the link "Test en" into Sanish language by changing the title with "Test es"

checking the database I see that both table "menu_link_content" and table "menu_link_content_data" have bundle values as "menu_link_content"

By installing the taxonomy_menu_ui module and applying the patch, I can correctly insert and translate menu items from the taxonomy term edit form.

Searching through the core issues, I found these two that go in the direction of keeping the bundle at menu_link_content, but none where it is specified to use the bundle equal to the menu_name

tom_ek’s picture

I can confirm that the patch from #8 fixes the issue.

Basically when the menu item is saved, the entity validator tries to load the proper TypedData for the entity type and bundle. But menu_link_content has only one valid bundle, and that's menu_link_content. Passing menu name there will always trigger the error. I had it when saving any menu item after the hook_update_9001.

Basically menu_tree table is for the menu structure.

As @dewalt mentioned - I also don't think adding the menu name as the bundle could help with the translation. But might be I am missign something?

@kyrylo:
Here's where the bundle is set:
https://git.drupalcode.org/project/drupal/-/blob/11.x/core/modules/menu_...

  /**
   * {@inheritdoc}
   */
  public static function preCreate(EntityStorageInterface $storage, array &$values) {
    $values += ['bundle' => 'menu_link_content'];
  }

It's in the MenuLinkContent entity.

Comes from this ticket: https://www.drupal.org/project/drupal/issues/2923429

lobodakyrylo’s picture

@tom_ek I can’t reproduce the issue on fresh Drupal 11 install. It always saves menu name into bundle field. Also, if I enable menu translation, it only works if bundle contains menu name. If bundle will be menu_link_content, you will never have the ability to translate menu links.

nagy.balint’s picture

Just to report that I got this same issue yesterday on a site that we are maintaining for a long time.
"The "entity:menu_link_content:main" plugin does not exist. "

So the issue definitely happens often (at least on existing sites).

nagy.balint’s picture

In fact #8 not only fixed the issue, but also brought back the translate option in the menu admin (/admin/structure/menu/manage/main) which was missing after the module upgrade.
So it actually made it translatable again.

lobodakyrylo’s picture

Status: Needs work » Fixed

Status: Fixed » Closed (fixed)

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

dewalt’s picture

@lobodakyrylo I see you've found a proper solution (Git link), but why isn’t the commit linked to the ticket?

Also, an important point – what about giving credit to the people who found and described the bug, conducted the analysis, etc.? It doesn’t look good on your part.

lobodakyrylo’s picture

Status: Closed (fixed) » Needs review
StatusFileSize
new890 bytes

@dewalt good point. This is a patch that should be tested. It reverts changes from the previous update. I also pushed it to dev branch.

jsutta’s picture

Applied the patch in #22 against a fresh copy of our database without either this patch or the one in https://www.drupal.org/project/taxonomy_menu_ui/issues/3535088. It worked! @lobodakyrylo, thank you for jumping on this!

r-mo’s picture

StatusFileSize
new912 bytes

Update hook in #22 is missing $entity->save() so wasn't updating any broken entities in our existing install. Attached a patch to fix.

lobodakyrylo’s picture

@r-mo good point. I pushed changes to dev.

ronaldmulero’s picture

Thanks @r-mo #24 works for me to fix WSOD when saving "Edit menu link"

taxonomy_menu_ui 3.0.6

jcandan’s picture

Status: Needs review » Reviewed & tested by the community
lobodakyrylo’s picture

Status: Reviewed & tested by the community » Fixed

The fix has already been committed to the 3.0.x branch and included in the latest release.

The update hook now correctly restores the menu link bundle and saves the affected entities.

Thanks everyone for testing and confirming the fix.

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.