Problem/Motivation
Saving a node fails with "Non-translatable fields can only be changed when updating the current revision" when these three conditions are met:
- Content Moderation is enabled on the content type
- Content Translation is enabled on the paragraph type
- The paragraph type has non-translatable fields
This is the recommended configuration per [#2951436-67]: paragraph types should be translatable, but the ERR field on the node should not.
Content Moderation creates a non-default node revision (isDefaultRevision=FALSE) during form prepare. ERR propagates this flag to all paragraph entities. On save, Content Moderation corrects the node back to isDefaultRevision=TRUE, but that happens after paragraph validation has already fired. So the paragraphs still carry FALSE, and EntityUntranslatableFieldsConstraintValidator rejects any field changes.
I wrote a more detailed analysis with the full execution flow in [#3150084-70].
This has been discussed in the ERR queue for a long time ([#3150084]). The MR there changes storage behavior in ERR, which raised concerns about regressions ([#3150084-66], [#3150084-67]). As far as I can tell, ERR propagating the flag is correct. The timing problem seems to be in ParagraphsWidget, which runs validation while the paragraphs still carry the wrong flag. So I think the fix makes more sense here.
Steps to reproduce
- Enable Content Moderation on a content type.
- Enable Content Translation on a paragraph type used by that content type.
- Make sure the paragraph type has at least one non-translatable field.
- Create or edit a node and save.
Proposed resolution
ParagraphsWidget::massageFormValues() runs before validation, so it is possible to correct the flag there. The change is in-memory only. The save process recalculates the flag independently via entity_reference_revisions_entity_revision_create(), so storage and caching should not be affected.
// In ParagraphsWidget::massageFormValues(), after loading the paragraph entity:
if ($paragraphs_entity instanceof \Drupal\Core\Entity\RevisionableInterface
&& !$paragraphs_entity->isNew()
&& $paragraphs_entity->isTranslatable()
&& !$paragraphs_entity->isDefaultRevision()) {
$paragraphs_entity->isDefaultRevision(TRUE);
}
This runs at every nesting level since massageFormValues() is called recursively. I tested this with Published and Draft workflows on Drupal 11.2.9 with nested paragraphs (3 levels deep).
Remaining tasks
- MR with the fix
- Automated tests
- Review
User interface changes
None.
API changes
None.
Data model changes
None.
| Comment | File | Size | Author |
|---|---|---|---|
| #3 | validation-error-on-save-content-moderated-translatable-paragraphs.patch | 1.05 KB | adwivedi008 |
Issue fork paragraphs-3582767
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
Comment #3
adwivedi008 commentedCreated a patch for the issue with suggested changes
please review
Once verified Will port to an MR
Comment #4
scontzen commentedMR !242 already contains the fix and a functional test. Tested on Drupal 10.6.5 and 11.3.5.
Setting to Needs review.