New non translatable field on translatable content throws error

Created on 10 January 2019, over 5 years ago
Updated 7 May 2024, about 2 months ago

Problem/Motivation

Even when access is denied to a widget, the value submitted propagates to the entity built from the sum of widgets.

Steps to reproduce

  1. Enable at least content translation and content moderation modules and some entity providing module, node is typical.
  2. Set Hide non translatable fields on translation forms on the content translation admin form.
  3. Create an entity.
  4. Now add a nontranslatable field with a non-null default value.
  5. Try to add a non-default revision translation of the entity.
  6. Kaboom courtesy of EntityUntranslatableFieldsConstraint as the non-null value changes to the default. (error message "Non-translatable fields can only be changed when updating the original language.")

Proposed resolution

Don't let widgets pass their values when access is denied to them.

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

Original report by pavlosdan

We use *Paragraphs + Content Moderation + Translations*. We have a lot of content that is moderated and translated. We've added a new field in one of the paragraphs that did not need to be translatable (it's a checkbox that should be the same across translations) but we noticed that if a user attempts to edit existing published translated content holding said paragraph type prior to the original having a value for that field then the system throws a "Non translatable fields can only be changed when updating the current revision" error.

So far the only workarounds we could think of was to make the field translatable even though it didn't need to be.

Another possibility would be to remove the constraint as suggested here: https://www.drupal.org/project/drupal/issues/2955321#comment-12541730 🐛 Unable to change non-translatable field value on translatable content with content moderation enabled Needs work but we didn't test this.

Your thoughts on this would be greatly appreciated. :)

🐛 Bug report
Status

Needs work

Version

11.0 🔥

Component
Entity 

Last updated less than a minute ago

Created by

🇨🇦Canada pavlosdan

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

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • 🇨🇭Switzerland tcrawford

    I have applied patch #79 and tested. I am seeing warnings and errors though in core (and in paragraphs) when using the paragraphs module together with this patch.

    If I re-save the node in the original language before saving the translation, I see the following warning:

    ```
    Warning: Undefined array key "original_deltas" in Drupal\Core\Field\WidgetBase->flagErrors() (line 474 of core/lib/Drupal/Core/Field/WidgetBase.php).
    Drupal\Core\Field\WidgetBase->flagErrors(Object, Object, Array, Object) (Line: 2210)
    Drupal\paragraphs\Plugin\Field\FieldWidget\ParagraphsWidget->flagErrors(Object, Object, Array, Object) (Line: 270)
    Drupal\Core\Entity\Entity\EntityFormDisplay->flagWidgetsErrorsFromViolations(Object, Array, Object) (Line: 268)
    Drupal\Core\Entity\ContentEntityForm->flagViolations(Object, Array, Object) (Line: 214)
    Drupal\Core\Entity\ContentEntityForm->validateForm(Array, Object)
    call_user_func_array(Array, Array) (Line: 82)
    Drupal\Core\Form\FormValidator->executeValidateHandlers(Array, Object) (Line: 275)
    Drupal\Core\Form\FormValidator->doValidateForm(Array, Object, 'node_article_form') (Line: 118)
    ```
    If I don't resave the node in the original language first, but add a translation, I get the following TypeError.
    ```
    The website encountered an unexpected error. Please try again later.
    TypeError: Drupal\paragraphs\Plugin\Field\FieldWidget\ParagraphsWidget::errorElement(): Argument #1 ($element) must be of type array, null given, called in /app/docroot/core/lib/Drupal/Core/Field/WidgetBase.php on line 478 in Drupal\paragraphs\Plugin\Field\FieldWidget\ParagraphsWidget->errorElement() (line 2217 of modules/contrib/paragraphs/src/Plugin/Field/FieldWidget/ParagraphsWidget.php).
    Drupal\paragraphs\Plugin\Field\FieldWidget\ParagraphsWidget->errorElement(NULL, Object, Array, Object) (Line: 478)
    Drupal\Core\Field\WidgetBase->flagErrors(Object, Object, Array, Object) (Line: 2210)
    Drupal\paragraphs\Plugin\Field\FieldWidget\ParagraphsWidget->flagErrors(Object, Object, Array, Object) (Line: 270)
    Drupal\Core\Entity\Entity\EntityFormDisplay->flagWidgetsErrorsFromViolations(Object, Array, Object) (Line: 268)
    Drupal\Core\Entity\ContentEntityForm->flagViolations(Object, Array, Object) (Line: 214)
    Drupal\Core\Entity\ContentEntityForm->validateForm(Array, Object)
    call_user_func_array(Array, Array) (Line: 82)
    Drupal\Core\Form\FormValidator->executeValidateHandlers(Array, Object) (Line: 275)
    Drupal\Core\Form\FormValidator->doValidateForm(Array, Object, 'node_article_form') (Line: 118)
    Drupal\Core\Form\FormValidator->validateForm('node_article_form', Array, Object) (Line: 591)
    Drupal\Core\Form\FormBuilder->processForm('node_article_form', Array, Object) (Line: 323)
    Drupal\Core\Form\FormBuilder->buildForm(Object, Object) (Line: 48)
    Drupal\Core\Entity\EntityFormBuilder->getForm(Object, 'default', Array) (Line: 394)
    Drupal\content_translation\Controller\ContentTranslationController->add(Object, Object, Object, 'node')
    call_user_func_array(Array, Array) (Line: 123)
    Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() (Line: 580)
    Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 124)
    Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext(Array, Array) (Line: 97)
    Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() (Line: 169)
    Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
    Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 68)
    Drupal\simple_oauth\HttpMiddleware\BasicAuthSwap->handle(Object, 1, 1) (Line: 58)
    Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
    Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 106)
    Drupal\page_cache\StackMiddleware\PageCache->pass(Object, 1, 1) (Line: 85)
    Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 49)
    Asm89\Stack\Cors->handle(Object, 1, 1) (Line: 48)
    Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
    Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
    Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
    Drupal\Core\DrupalKernel->handle(Object) (Line: 19)

  • Status changed to Needs work over 1 year ago
  • 🇺🇸United States smustgrave

    Seems there was an error in #80, what steps did you follow?

    Testing on Drupal 10.1 with a standard install
    Added a date field to the basic page content type with a default value of current date.
    Installed content translation module
    Translating basic page but unchecking date field and checking hide non translatable fields
    Create a page leaving date as default
    Save
    Translate to another language
    Am able to save without failure

    Added a 2nd field to the basic page content type with a default value
    Still able to translate without issue

    Can someone provide new testing steps.

  • 🇩🇪Germany Anybody Porta Westfalica

    Closed 🐛 Message "Non-translatable fields can only be changed when updating the original language." without specifying the concerning fields Closed: duplicate as duplicate. I agree that at least naming the affected field in the error message would be helpful to find out, what's wrong.

  • 🇩🇪Germany Anybody Porta Westfalica
  • 🇺🇦Ukraine lobodacyril

    Comment #75 worked form me. Thank you.

  • 🇧🇪Belgium herved

    #32 indeed a new untranslatable boolean field with previously existing translations is enough to cause this.
    Upon saving one of the translations we get the error message.
    The EntityUntranslatableFieldsConstraintValidator can trigger for other reasons but this here is one of them and can happen with just nodes.

    Here are my steps:
    - Install standard drupal profile
    - At /admin/modules: Enable the content translation module
    - At /admin/config/regional/language: add a language
    - At /admin/config/regional/content-language: enable translation for Content > Article + check "Hide non translatable fields on translation forms"
    - At /node/add/article: add an article node (just the title is enough) + create a translation
    - At /admin/structure/types/manage/article/fields/add-field: create a new boolean field (leave it as untranslatable)
    - Go back to the node translation edit form, update the title and attempt to save > we get "Non-translatable fields can only be changed when updating the original language."

    EntityUntranslatableFieldsConstraintValidator will return TRUE for hasUntranslatableFieldsChanges because the boolean field items went from nothing to something (a BooleanItem with [value => FALSE]. It will then trigger the error if hasTranslationChanges returns TRUE, which it will if changes are detected on any translatable fields (e.g: title).
    Breakpoints here and there help.

    Patch #79 works for me, thanks.

  • 🇺🇸United States amaisano Boston

    I am experiencing this issue but with a slightly different context.

    None of the patches here worked.

    Similar to https://www.drupal.org/project/drupal/issues/3026055 (no solution), I have a taxonomy term in English that has a File (Image) field that has a value for it. In my content translation settings, I have the term's Image field marked as translatable because we need to alter the ALT text for it per language, but the "File" attribute is UNchecked, because we don't need a different image per language.

    On the French translation of this term, I cannot save any changes due to the "Non-translatable field elements can only be changed when updating the original language" error.

    If I go back to the English version and remove the image (and save the English version), then I can once again make changes to fields and save the French translation without problems.

  • It's work for me.

    I have had checkbox field and At first didn't work but when I remove field and add other type(date) starts work. :)

    Single on/off checkbox(Img1) must be Check boxes/radio buttons(img2) and all work.

    I don't know about taxonomy term but maybe it will work for term.

  • Or you can use patch this patch.

  • last update 8 months ago
    Patch Failed to Apply
  • Open in Jenkins → Open on Drupal.org →
    Environment: PHP 8.1 & MariaDB 10.3.22
    last update 8 months ago
    30,343 pass
  • Status changed to Needs review 8 months ago
  • last update 8 months ago
    30,213 pass, 99 fail
  • 🇮🇳India _utsavsharma

    #88 failed to apply .

  • Status changed to Needs work 8 months ago
  • 🇺🇸United States smustgrave

    Wasn’t able to replicate but maybe test coverage will show it better. That will be needed

  • Patches don't work correctly(drupal 9.5/10).

    Reproduce

    1. Site is multilingual (there are 3 languages)
    2. Create field in the Article CT which type is link(non translatable, unlimited)
    3. Need only URL (Allow link text is disabled )
    4. create new Article and set 3-4 ULRs(working great)
    5. Translate node and click save
    6. Throw errors (img)
    7. 2th time we can't translate the same translation.
  • 🇩🇪Germany stBorchert

    Hey. We use the latest patch and it breaks creating content when using content moderation for content types.

    Steps to reproduce

    :

    • setup a default workflow for content moderation ("Draft", "Published")
    • set the initial state to "Draft"
    • select a content type (e.g. "Page") to use the workflow
    • go to node/add/page (or whatever your selected content type has been named)
    • do no update the workflow state (leave as "Draft")
    • save the node

    This will result in

    EntityStorageException: SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'status' cannot be null ... 
    

    This happens because the patch explicitly sets the value of field "status" to NULL:

    $items->setValue(NULL);
    

    This is wrong for fields that must not be null (based on their schema), e.g. for "status" null-values are not allowed.

  • 🇪🇸Spain akalam

    I can't reproduce the bug anymore following the steps from #46 on drupal 10.2

  • 🇺🇦Ukraine loon Lutsk

    Updated patch #79 with fix the issue described in #92

  • 🇺🇸United States mgaskey

    Anyone still experiencing this issue using D10.2+ and content moderation should note that the latest patch in #94 will fail as the code is already added to Core.

    We experienced the effects of the current issue after having added a boolean field to all content types, which all have translations enabled. We could not save a new translation without manually saving the base node first.

    The patch in https://www.drupal.org/project/drupal/issues/2955321 🐛 Unable to change non-translatable field value on translatable content with content moderation enabled Needs work (#77) fixes the issue for us.

  • 🇨🇦Canada joseph.olstad

    an easy workaround for this is to put a non-translatable field for each language in your paragraph.

    example:

    paragraph bundle:
    fields:
    field_example
    field_example_fr
    field_example_de

    field_example2
    field_example2_fr
    field_example2_de

    then preprocess the fields to display when desired.

Production build 0.69.0 2024