InvalidArgumentException: Invalid translation language (en) specified

Created on 25 February 2025, about 2 months ago

Problem/Motivation

\Drupal\custom_field\Plugin\CustomFieldWidgetBase::widget() uses the interface language to load the parent entity translation. This is problematic if interface and content language differ.

Steps to reproduce

  • Create an entity with a custom field in a certain language
  • Set the site so the interface language is fixed to another language
  • Try to edit the entity again, while making sure the interface language is still different from the entity language.

Proposed resolution

Getting the active content language using LanguageInterface::TYPE_CONTENT fixes the problem and should main the current behaviour if both interface and content language (detection) are the same.

πŸ› Bug report
Status

Active

Version

3.1

Component

Code

Created by

πŸ‡§πŸ‡ͺBelgium andreasderijcke Antwerpen / Gent

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

  • Issue created by @andreasderijcke
  • πŸ‡§πŸ‡ͺBelgium andreasderijcke Antwerpen / Gent
  • Pipeline finished with Success
    about 2 months ago
    Total: 555s
    #433529
  • πŸ‡ΊπŸ‡ΈUnited States apmsooner

    Can you give some more steps on how to reproduce this? I have an entity already created in english which is my default language. I've added a new language (spanish). Should i change default language here: /admin/config/regional/language to spanish? I tried that and edited the node but didn't see any issues. There must be some other configuration steps i'm missing.

  • Pipeline finished with Skipped
    about 1 month ago
    #434790
  • πŸ‡ΊπŸ‡ΈUnited States apmsooner

    Wasn't able to reproduce but looking at the patch now and seeing the default type, it totally makes sense for your fix so I'm merging. Thanks for the patch!

  • πŸ‡§πŸ‡ͺBelgium andreasderijcke Antwerpen / Gent

    Ah, sure. I guess "if interface and content language differ" is indeed to vague.

    Something like this:

    (The "Selected language" is identical for both interface and content, as-in they share the value, set to default site language).

    Point is to get to active language for interface and content to differ, one way or another.
    That this can happen is often overlooked, both in core and contrib. Core does not always separate interface and content properly either, many issue about that.

    Just imagine, you have editors with different native languages, and they each one wants to have the interface in their own preferred language (hence the "Account administration pages" enabled for interface) but they all managed content in all available languages.

    So, in my specific case, I tried to edit an existing node with custom field with only NL translation (source) while having the interface forced to EN.
    In that case, the code (pre) patch would use EN as default language to load the entity in for access checking, while it might not exist (yet) in that language. The content language does return NL in that case, since we're indeed editing the entity in that language.

    PS: While trying to post the commit, the issue was already set to fixed. But submitting this anyway for future reference.

  • πŸ‡§πŸ‡ͺBelgium andreasderijcke Antwerpen / Gent
  • πŸ‡ΊπŸ‡ΈUnited States apmsooner

    Thanks for the detailed explanation! Yes, i went ahead and already merged it: https://www.drupal.org/project/custom_field/issues/3508870#comment-16004809 πŸ› InvalidArgumentException: Invalid translation language (en) specified Active

  • πŸ‡ΊπŸ‡ΈUnited States apmsooner
  • πŸ‡§πŸ‡ͺBelgium swentel

    There's actually no guarantee there is a translation too for the entity. If not, it will crash

    This is the current fix I have for now, but I'm not sure if it's the proper one. But at least it doesn't crash for now.

    (which reminds me I should make a follow up for the formatter_settings crash, but close on a deadline atm)

    diff --git a/src/Plugin/CustomFieldWidgetBase.php b/src/Plugin/CustomFieldWidgetBase.php
    index 51e544cdf..00e5b26ea 100755
    --- a/src/Plugin/CustomFieldWidgetBase.php
    +++ b/src/Plugin/CustomFieldWidgetBase.php
    @@ -112,7 +112,7 @@ public function widget(FieldItemListInterface $items, int $delta, array $element
           $langcode = $this->languageManager->getCurrentLanguage(LanguageInterface::TYPE_CONTENT)->getId();
           $is_default_translation = TRUE;
           $is_translatable = $field_definition->isTranslatable() && $field->getWidgetSetting('translatable');
    -      if (!$entity->isNew()) {
    +      if (!$entity->isNew() && $entity->hasTranslation($langcode)) {
             $entity = $entity->getTranslation($langcode);
             $is_default_translation = $entity->isDefaultTranslation();
           }
    
  • πŸ‡§πŸ‡ͺBelgium andreasderijcke Antwerpen / Gent

    @swentel: What's the context of your case?
    Inline entity form perhaps?

  • πŸ‡§πŸ‡ͺBelgium swentel

    @andreas no, just regulary entity forms, created an issue at πŸ› Entity translation does not necessarily exist Active

  • πŸ‡ΊπŸ‡ΈUnited States apmsooner

    @andreasderijcke, can you weigh in with a review on that patch in https://www.drupal.org/project/custom_field/issues/3510744 πŸ› Entity translation does not necessarily exist Active please?

  • πŸ‡§πŸ‡ͺBelgium andreasderijcke Antwerpen / Gent

    That patch makes indeed sense.

    I'm just wondering if there are other situations where the current (content) language will not match entity (translation) being edited or created.

    In my language (detection) setup, the $entity->getTranslation() is returning the default translation of the entity because of the fallback logic in \Drupal\Core\Entity\EntityRepository::getTranslationFromContext().
    Any module affecting this fallback logic, could indeed lead to different result.

Production build 0.71.5 2024