I am still trying to narrow down this causally!

I have a scenario, where I have nested paragraphs:

Node entity bundle has fields:
-> Row (multi-value single paragraph type)
   -> Column (multivalue from 4 different types of paragraphs)

The client often uses the preview button when building up these nodes, and frequently encounters the following contstraint violation error:

The content has either been modified by another user, or you have already submitted modifications. As a result, your changes cannot be saved.

In debugging, I can track the violation down to one of the landing page rows (using xdebug)

In the entity constraint code we have:

\Drupal\Core\Entity\Plugin\Validation\Constraint\EntityChangedConstraintValidator

  public function validate($entity, Constraint $constraint) {
    if (isset($entity)) {
      /** @var \Drupal\Core\Entity\EntityInterface $entity */
      if (!$entity->isNew()) {
        $saved_entity = \Drupal::entityManager()->getStorage($entity->getEntityTypeId())->loadUnchanged($entity->id());
        // A change to any other translation must add a violation to the current
        // translation because there might be untranslatable shared fields.
        if ($saved_entity && $saved_entity->getChangedTimeAcrossTranslations() > $entity->getChangedTimeAcrossTranslations()) {
          $this->context->addViolation($constraint->message);
        }
      }
    }
  }

On examination of the offending row paragraph, the revision ids between the $saved_entity and the $entity are different, as are the saved times.

Is this a core issue, or a paragraphs issue? Shouldn't the entity storage handler properly load the latest entity revision?

Comments

jaxxed created an issue. See original summary.

jaxxed’s picture

Issue summary: View changes
jonathanshaw’s picture

I have seen the same error. I've also experienced something that may be related:
a paragraph type A (that has only a single field P1, of type entity ref revisions paragraphs) becoming corrupt in some way such that when ever using the node edit form for some new or existing node this paragraph type A is placed in a paragraphs field P2 on the node, AND another paragraph type B is then placed in A's field P1, the node will not save and gives WSOD.

However, I've not been able to replicate how to cause this to happen.

I can create a new paragraph type, and add field P1 to it, and that works fine! It's as if the original type has become corrupted in some way.

jonathanshaw’s picture

Priority: Normal » Critical
StatusFileSize
new896.85 KB

I still have not managed to find a way to replicate the bug(s), but I have seen further (possibly related) strange things while using nested paras.

Consider the screenshot below. The right side "After refresh" shows what I saw after pressing the browser's refresh button, i.e. the true saved state of the node. The left side "Before refresh" shows what I was seeing before I pressed the refresh button.

The field "Paragraphs" has somehow become duplicated on the page, it has rendered again inside itself! There was a paragraphs field on a nested paragraph, but for some reason the root paragraphs field rendered instead of it.

I'm suggesting a bump to critical - although not yet reproducible - because there are all sorts of possibility for data loss in the bug(s) discussed in this thread.

I'm happy to spend more time trying to find a reproducible procedure for triggering a bug, but I'd really appreciate any suggestions on what things to test out.

(Ignore the strange styling in the left screenshot, I was playing with CSS tweaks for usability; nothing that I can imagine causing this though).

jonathanshaw’s picture

I've got an idea what might be at work here. Consider the following field id produced in a nested situation:
"field-paragraphs-0-subform-field-paragraphs-2-0-subform-field-paragraphs-1-1-subform-field-paragraphs-1-add-more-wrapper"

If I understand right, entity revisions are getting appended to field names with a dash, so the first revision of field "myfield" gets marked "myfield-1" in some contexts.
However, field names that contain underscores also get converted into dashes, so "myfield_1" becomes "myfield-1" too.

In the first situation I ran into trouble, I had fields "paragraphs", "paragraphs_1" and "paragraphs_2". When the same paragraphs field is getting used multiple times on a page (because of nesting, and reusing fields between paragraph types) this extra confusion of field names with underscores might break something?

pingers’s picture

Also experienced the issue - couldn't reproduce independently though.

I'm looking into the database to try and see what has broken. Struggling to find anything though.

The workaround I found was to delete the paragraph entities in the node and recreate them into new paragraphs.

jonathanshaw’s picture

It might help if we posted database extracts. That way someone might be able to figure out what's going on. Can anyone suggest which database tables it would be good to include?

hauruck’s picture

Issue tags: +SprintWeekendBerlin
hauruck’s picture

I have had the same issue. The problem lies in the InlineParagraphsWidget.php, here the paragraphs will take what it believes to be the latest revision of the content and send it off for validation on save. This validation compares the paragraphs revision with the latest revision (really latest) of the content and throws an error if the time stamp of the latest revision is higher then the revision sent off for validation. Paragraphs forgets that revisions can be created outside of paragraphs and the assumption that the revision that you are trying to save always is the latest is false. For example when you hit the preview or edit the nested content directly you have a created a new revision of the content. A revision that Paragraphs doesn't know about but will be a later version that causes the validation to fail.

Proposed solution: The time stamp of the revision you are trying to save is set to now before validation, thus passing the time constraint.

hauruck’s picture

jonathanshaw’s picture

Status: Active » Needs review

Hauruck, you've made me very happy! Let's see what testbot has to say ...

Status: Needs review » Needs work

The last submitted patch, 10: paragraphs-EntityChangedConstraintValidator-2631590-9.patch, failed testing.

The last submitted patch, 10: paragraphs-EntityChangedConstraintValidator-2631590-9.patch, failed testing.

The last submitted patch, 10: paragraphs-EntityChangedConstraintValidator-2631590-9.patch, failed testing.

webflo’s picture

Assigned: Unassigned » webflo
Issue tags: +SprintWeekend2016

Fixed the failing test in #2659560: Fix Paragraphs tests. Its not related to this issue.

hauruck’s picture

I have written a patch for the administration test to also check for this validation problem.
The second file is a combination of the test and the fix.

cyberschorsch’s picture

Status: Needs work » Needs review

cyberschorsch’s picture

I tested this with success, not sure why the testbot is failing.

Requeued the failed test.

jonathanshaw’s picture

It's failing because it's a test only patch and is expected to fail. It's the combined test&fix patch that needs to pass.
If the patch is named "xxxxxx-do-not-test.patch" then the testbot will not try it and the issue will not get set back to Needs review.

webflo’s picture

Patch from #16 again.

pontus_nilsson’s picture

Patch fixes our issue with nested paragraphs and the changed validation. Do we need to do something about the tests to push this forward?

miro_dietiker’s picture

Isn't setting the changed date a workaround?

From what you described on #9, it seems we are wrongly treating revision handling... If this is solved, the issue would similarly disappear i'd expect?

webflo’s picture

I think it is more or less a limitation of the EntityChangedConstraint. The EntityChangedConstraint loads the active revision of the given entity, but paragraphs operates on a complete different entity revision and the active revision is not relevant in this case. Paragraphs won't use it anyway, because the revision is tracked in the field itself and used to display the actual content.

miro_dietiker’s picture

OK i see, but...
"For example when you hit the preview or edit the nested content directly you have a created a new revision of the content."
I don't think we are saving new revision while previewing intentionally. Seems like an undesired effect to me?

jonathanshaw’s picture

Has anybody figured out the steps to reproduce? Might help the discussion.

michaellenahan’s picture

Cross-referencing: https://www.drupal.org/node/2597201#comment-10873134

I was getting the problem with EntityChangedConstraintValidator and the error: "The content has either been modified by another user, or you have already submitted modifications. As a result, your changes cannot be saved."

However, in my case it was not with nested paragraphs, just regular un-nested ones.

killua99’s picture

This has some relation. Because I'm having some problem with the paragraph and image fields. No idea is this happen before. When do you have 2 images the second one start to getting the first image instead.

Reference;

https://www.drupal.org/node/2671378#comment-10881276

stewest’s picture

I'm getting this too. I have a Paragraph with 3 paragraphs in it. I have multiple translations for this node.
I cannot save the node whether I leave on, or switch off "Create new revision (all languages)"

Paragraphs Version: 8.x-1.0-rc4
Drupal 8.0.3

I started with:
The website encountered an unexpected error. Please try again later.

Drupal\Core\Entity\EntityStorageException: SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '91099814-88b1-440a-9e00-beabb7c8eb7f' for key 'paragraph_field__uuid__value': INSERT INTO {paragraphs_item} (revision_id, type, uuid, langcode) VALUES (:db_insert_placeholder_0, :db_insert_placeholder_1, :db_insert_placeholder_2, :db_insert_placeholder_3); Array ( [:db_insert_placeholder_0] => [:db_insert_placeholder_1] => highlights [:db_insert_placeholder_2] => 91099814-88b1-440a-9e00-beabb7c8eb7f [:db_insert_placeholder_3] => en ) in Drupal\Core\Entity\Sql\SqlContentEntityStorage->save() (line 757 of core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php).

Then:
Fatal error: Call to undefined method Drupal\Core\TypedData\Plugin\DataType\IntegerData::isEmpty() in /var/www/localsearch_ch_dev/public_html/core/lib/Drupal/Core/Entity/Plugin/Validation/Constraint/ValidReferenceConstraintValidator.php on line 78

Then:
Notice: Undefined property: Drupal\Core\TypedData\Plugin\DataType\IntegerData::$target_id in Drupal\Core\Entity\Plugin\Validation\Constraint\ValidReferenceConstraintValidator->validate() (line 74 of core/lib/Drupal/Core/Entity/Plugin/Validation/Constraint/ValidReferenceConstraintValidator.php).

killua99’s picture

stewest’s picture

Thanks. I updated to dev version of Paragraphs, and I updated to latest release of entity_reference_revisions (rc-4)
Following the Readme.txt, I also set the Translation options accordingly, here admin/config/regional/content-language

I switched off Revisions.

I can now save

killua99’s picture

But still you could use revisions (I'm using them) when you apply all those patches (3 to be sure).

jonathanshaw’s picture

Responding to @miro_dietiker #26:

OK i see, but...
"For example when you hit the preview or edit the nested content directly you have a created a new revision of the content."
I don't think we are saving new revision while previewing intentionally. Seems like an undesired effect to me?

Regardless of whether preview triggers this issue or not, editing does, and the patch addresses that.

Is this patch RTBC as a solution to editing of nested entities?

We could open a separate new task issue "Assess new revisions on preview" to see if that is happening and decide how to address it.

miro_dietiker’s picture

Status: Needs review » Needs work

I have created this issue to address the origin of the problem:
#2676098: Do not save in widget

Independent of this, i agree that we can commit a workaround here to unlock the situation, because fixing the other issue is challenging, given that you add a comment to the fix and @todo to remove the workaround once the root cause is fixed (link to the other issue).

jonathanshaw’s picture

It's fantastic that #2676098: Do not save in widget has landed. However, it doesn't appear to solve all of the problems we've discussed on this thread. I've managed to isolate a reproducible example and created a new issue for it: #2706603: Do not validate during form submission

berdir’s picture

Priority: Critical » Normal
Status: Needs work » Postponed (maintainer needs more info)

Still pretty sure that we can close this. Since #2676098: Do not save in widget, we no longer save on preview, so this can simply no longer happen. If there are still issue,s then please open new issues, as you already did with the example above.

davidneedham’s picture

Like some others here, I don't have nested paragraphs, and I'm not clicking preview but I'm still seeing this error on Drupal 8.0.6 with the latest Paragraphs 8.x-dev. Perhaps this should be a separate issue? I'm using a content type with revisions disabled and only a single paragraphs field and no others. Whenever I try to create new content of this type, I get the error.

I'm using Paragraphs as a replacement for the default body field, so I have a paragraphs field that lets people choose between text, image, and file. Since it's a body replacement and text is the common starting place, I choose that as a default. I just tried editing the Paragraphs field on the content type in manage fields and I got this error when I click save on that configuration. It must be the default field (for me, at least).

If I remove the default field it starts working normally - both in configuration and in creating new content.

miro_dietiker’s picture

Please provide exact steps to reproduce. We can't see this happening.

webflo’s picture

Assigned: webflo » Unassigned
davidneedham’s picture

I just ran through this on simplytest.me, but it's not happening there under the conditions I mentioned. I guess it's being caused by something else.

jonathanshaw’s picture

Do you get it with new nodes, or only ones that you have worked on before updating to the latest paragraphs?

davidneedham’s picture

I wasn't using the Dev version of Paragraphs until I started seeing this problem, and it looks like the simplytest.me site I spun up was using the non-Dev version of Paragraphs as well.

Note: I was getting this with new nodes AND when managing fields to edit the paragraph field on the content type. It seemed like simply displaying the default field with a textarea in it caused it to happen. But as I said, I couldn't recreate this when I tried over at simplytest.me.

berdir’s picture

Can you clarify "default field" and the steps you took to to configure it exactly?

I think having a default field is simply something that's not possibly due to the way things work. Every paragraph belongs to exactly one host entity, having a default is essentially re-using that default paragraph in multiple places.

Of course, it shouldn't fail that bad and we should either find a way to support it (clone it initially?) or have a separate setting for a default paragraph.

What would help is you can either post the error from your php logs or enable display errors so the error is visible.

davidneedham’s picture

Here are the steps to add a default field:

  1. Edit a content type > manage fields
  2. Edit the existing Paragraphs field
  3. Scroll down to "Default value" and select "Text" from the dropdown button. (Text is a Paragraph type I created that has only a long text field in it).
  4. Click save.

It's worth noting that when I select a default value from the dropdown button, two textareas actually appear.

If I try to go through my steps above I now get:

The website encountered an unexpected error. Please try again later.

Drupal\Core\Entity\EntityStorageException: SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'langcode' cannot be null: INSERT INTO {paragraphs_item} (revision_id, type, uuid, langcode) VALUES (:db_insert_placeholder_0, :db_insert_placeholder_1, :db_insert_placeholder_2, :db_insert_placeholder_3); Array ( [:db_insert_placeholder_0] => [:db_insert_placeholder_1] => textarea [:db_insert_placeholder_2] => 2cf1a94a-f7df-4306-b96b-3d4c366bc321 [:db_insert_placeholder_3] => ) in Drupal\Core\Entity\Sql\SqlContentEntityStorage->save() (line 757 of core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php).

I removed the Paragraph field from the content type and added it again without any errors. I can edit the field and click save without any changes and it works on this new field (instead of showing the error above). However, if I go through my steps above to add a default value, I get this error:

The website encountered an unexpected error. Please try again later.

Drupal\Core\Entity\EntityStorageException: SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'langcode' cannot be null: INSERT INTO {paragraphs_item} (revision_id, type, uuid, langcode) VALUES (:db_insert_placeholder_0, :db_insert_placeholder_1, :db_insert_placeholder_2, :db_insert_placeholder_3); Array ( [:db_insert_placeholder_0] => [:db_insert_placeholder_1] => textarea [:db_insert_placeholder_2] => d647c995-a01b-482c-ac60-c8027d8ed30a [:db_insert_placeholder_3] => ) in Drupal\Core\Entity\Sql\SqlContentEntityStorage->save() (line 757 of core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php).
ciss’s picture

Status: Postponed (maintainer needs more info) » Active

Edit 2: The below scenario (reverting revisions) is unrelated. See comment #47.

Steps to reproduce:

  1. Enable Paragraphs demo.
  2. Edit Paragraphs article "Welcome to the Paragraphs Demo module!"
  3. Check "Create new revision" and save.
  4. Revert to previous revision.
  5. Edit and (try to) save again.

Tested with 8.x-1.x branch on simplytest.me.

Edit: Hopefully I'm not highjacking this issue. I suspect this is strongly related to the problem initially mentioned since the error gets triggered by EntityChangedConstraintValidator for all paragraphs items.

berdir’s picture

That part is covered by #2715855: Remove changed field to fix changed validation when trying to update old revisions now. Not sure if there's another issue to resolve here.

ciss’s picture

Status: Active » Postponed (maintainer needs more info)

My bad, sorry for the noise. Setting back to postponed.

berdir’s picture

No worries. I think we rediscovered this problem in another issue and opened a new one. Forgot about updating this one. Another confirmation that the patch there solves that problem would be great. Currently working on test coverage.

oknate’s picture

I have opened new issue for the same error message in comment 45.