I'm not exactly sure what is going on here but I've finally managed to find a way to reproduce this error consistently.

Set up

  1. Create a content type with an image field
  2. Add an entity reference field that references "Other > Configuration > Block"
  3. Ensure you have a View on the site with a block display (e.g. "Who's Online") and that it is placed in a region

Steps

  1. Create a node and in the block entity reference field, choose your Views block (e.g. "Who's Online")
  2. Save the node - the views block should render fine
  3. Open the node for editing
  4. Upload an image in the image field
  5. The ajax should fail and you should get the error below on screen in your inspector console, failing that it might appear on node save.

Fatal error: Call to a member function getFieldStorageDefinition() on array in core/lib/Drupal/Core/Field/TypedData/FieldItemDataDefinition.php on line 66

Line 66 is return $this->fieldDefinition->getFieldStorageDefinition()->getPropertyDefinitions();.

From a bit of debugging, I can see that $this->fieldDefinition is indeed an array and contains the following: Array ( [class] => Array ( [0] => node-page-edit-form [1] => node-form ) [data-drupal-selector] => node-page-edit-form )

The above steps reproduces the error consistently for me. I've noted the following however:

  • There's no issue editing fields which do not rely on AJAX (e.g. title field)
  • You can reference regular blocks or custom block types and you won't get the error. It only happens with Views blocks afaict
  • I've used the image uploader as a simple way to trigger it, but any ajax operation on the page should trigger it.

Comments

stella created an issue. See original summary.

stella’s picture

Issue summary: View changes
samuel.mortenson’s picture

I'm also seeing this intermittently with Panels IPE, but for me $this->fieldDefinition is a string containing the Plugin ID of the Block I'm placing.

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.9 was released on September 7 and is the final bugfix release for the Drupal 8.1.x series. Drupal 8.1.x will not receive any further development aside from security fixes. Drupal 8.2.0-rc1 is now available and sites should prepare to upgrade to 8.2.0.

Bug reports should be targeted against the 8.2.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

cman9090’s picture

I'm getting this exact same issue. Same steps to reproduce error. I've tried following https://www.drupal.org/node/2443165 and all related nodes, nothing has helped.

shadcn’s picture

I can still reproduce this on 8.4.x.

It looks like this is coming from entity_reference_autocomplete. If I switch the block reference field to a select list, error is gone.

@cman9090 can you confirm this please?

berdir’s picture

#2831521: Avoid unserialization of blockPluginCollection in BlockDisplayVariant is related, which fixes many such problems in page_manager/panels.

Haven't seen it yet just in core, but it is probably something else that is getting serialized and shouldn't and then causes unserialize bugs.

Note: Block entity reference fields, the standard reference field? That's IMHO the wrong way to do that, consider using the block_field project instead which allows to reference the block *plugin* and not a block config entity, which is designed and built to be displayed in a specific theme in a region, with visibility conditions.

pingwin4eg’s picture

I have the same error, but with another case.

I try to run operations in a batch from a views bulk form on entities of a custom type. The view has an argument - the entity reference field, which refers to an entity of another custom type by numeric ID. Both entity types are Content Entity Types. This view arg has a validation checkbox checked, that current user must have a 'view' access on referenced entity. This referenced entity has 'uid' field as a reference to entity owner. An error occurs in this 'uid' field, when the access handler attempts to fetch the owner ID from an entity.

Here is my error backtrace.

The weird thing is that the guilty array contains something that I didn't expect to see:

array(1) {
  ["data-drupal-selector"]=>
  string(23) "edit-show-view-elements"
}
haza’s picture

Got more or less the same issue, trying to execute (or preview) a views using a searchAPI as backend in a batch operation.

berdir’s picture

As I said, all of those indicate very large objects being serialized that then result in bugs on unserialize, which looks like a PHP bug then.

Something is not properly using DependencySerializationTrait as the ctools example above, maybe core, maybe some other module like search_api. The only way to figure this out is try to look at the serialized data structures being created in cache/key_value_expire, and trying to figure out what kind of object you have in ther that is so bug and messing up everything.

shadcn’s picture

StatusFileSize
new186.41 KB

@Berdir for my test in #7, this was with core 8.4.x (no contrib): \Drupal\Core\Field\TypedData\FieldItemDataDefinition::getPropertyDefinitions.

I'll look into this a bit more tomorrow.

pingwin4eg’s picture

I've debugged my case a little. And found that the fieldDefinition property is serialized as a reference (r:49;) when being cached. I didn't count 49 items, but as far as I understood it refers to proper BaseFieldDefinition object. So I guess the problem is with UNserialization here.

@Berdir are you proposing to remove the fieldDefinition property before serializing an object (like it's done with block plugins in a mentioned issue)?

berdir’s picture

I'm not sure what object needs to be removed, likely not the field definition, we can only remove services that we can re-inject or things that we can re-create like plugin collections. A field definition should be a simple object without external dependencies.

your dump looks small to me, not sure why that would be a problem. Mine that failed where multiple hundred kilobites and had *everything* in them.

On the other hand, yours might be small enough so you could re-create it in a more or less standalone PHP script. Then we might be able to create a php bug report.

berdir’s picture

I'm not sure that's the right cache entry though. Can you post a full backtrace of where this happens?

pingwin4eg’s picture

Here is the initial backtrace when the Error happens: https://gist.github.com/mikeshiyan/3f6342f8f870a49443eca5dd540893ae - when the method is called on array. Then I started to debug that trace from the beginning of request to find when the fieldDefinition property becomes an array.

I found out that before Drupal\Core\Entity\ContentEntityBase->getTranslatedField('uid', 'x-default') the property is not set yet. From that point:

  1. \Drupal\Core\Entity\ContentEntityBase::getFieldDefinition()
  2. \Drupal\Core\Entity\ContentEntityBase::getFieldDefinitions()
  3. \Drupal\Core\Entity\EntityFieldManager::getFieldDefinitions()
  4. \Drupal\Core\Entity\EntityFieldManager::getBaseFieldDefinitions()
  5. \Drupal\Core\Cache\UseCacheBackendTrait::cacheGet() with $cid = 'entity_base_field_definitions:' . $entity_type_id . ':' . $this->languageManager->getCurrentLanguage()->getId(); and EntityFieldManager service uses @cache.discovery as backend.

And cache is in place. I tried to delete this entry and return back to page from which I start the batch process. It renders without an error, and this cache entry is recreated here. Perhaps that page even uses this cache entry when it exists (I didn't test), so unserialization by itself should not be the problem.

But when I see the result of cacheGet() the array is already there in fieldDefinition property. So right now I can't understand how is that even possible.

P.S.: I forgot to mention I use core 8.2.5 in my project. Maybe in later versions field definitions are stored in another cache bin? I haven't checked it yet.

cman9090’s picture

@arshadcn can confirm using autocomplete with block config reference. I've built an entire portal 100's of nodes are populated with entity block config references so redoing it with block_field is not my first go-to. I've changed the form display from autocomplete to select list and it appears to be working now.

pingwin4eg’s picture

I think I found the cause. Seems like a PHP bug in unserialize() function. Precisely in nested unserialization.

Let's look at my case, for example.

  1. 1st unserialize() is called in BatchStorage->load().
  2. Inside it a ViewExecutable object is being unserialized.
  3. Inside it a cached data is being unserialized for field definition.

The last serialized string (the cached entity_base_field_definitions item) contains references (like r:2, r:49, etc.) The numbers refer to objects from the current serialized string. But, nobody knows why, in the unserialization process the values from the very 1st serialized string are assigned instead (in preserved order).

So in my case the r:2, which should be the BaseFieldDefinition object for the 'sid' field, on unserialization becomes the batch 'sets' array. And r:49, also the BaseFieldDefinition object but for the 'uid' field, becomes a {["data-drupal-selector"]=>"edit-show-view-elements"} array, which also present in $batch array.

pingwin4eg’s picture

There's already a 3-year-old bug report @ https://bugs.php.net/bug.php?id=66052

shadcn’s picture

@cman9090 I mean you don't need to change the field. You can just change the widget.

pingwin4eg’s picture

StatusFileSize
new1.34 KB

This is a very-very rough workaround of the nested unserialize() bug. It covers only cases with Views and Database cache backend.

Don't use it on live projects. Seriously. Just for development.

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.6 was released on February 1, 2017 and is the final full bugfix release for the Drupal 8.2.x series. Drupal 8.2.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.3.0 on April 5, 2017. (Drupal 8.3.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.3.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

pingwin4eg’s picture

Parent issue: » #2849674: Complex job in ViewExecutable::unserialize() causes data corruption

Created a new issue, specifically for the unserialization bug. Seems like all reports here in this issue are caused exactly by it.

mxh’s picture

The only thing I have noticed so far is that in ViewExecutable , when its ::serialize() method calls the PHP function serialize() - whether or not returned its value - leads to the problem.

Example (seems to only apply for ViewExecutable):

<?php
public function serialize() {
    serialize('Something unrelated to this instance');
    return '... nothing from serialize() but will lead to data corruption';
  }
?>

When commenting out the line with the serialize-instruction, the data corruption is not happening...

mxh’s picture

Title: Fatal error: Call to a member function getFieldStorageDefinition() on array » ViewExecutable might break serialization of its own and other data
Component: field system » base system
Status: Active » Needs review
StatusFileSize
new4.59 KB

Trying to write the cause of this problem into the title for better addressing.
I'm also changing the affected component, since this issue is very likely a common object serialization problem.
Feel free to change it if it's still not suitable.

Attaching a patch which replaces the Serializable implementation by an alternative using magic methods.
By this, I also removed the usage of DependencySerializationTrait, because it seems that it had no use anyway (__sleep() and __wakeup() aren't used anymore when a class implements the \Serializable interface). I haven't found any other point where this might be relevant, thus removed.

mxh’s picture

Component: base system » views.module

Changing the component again, sorry - the cause of the issue here solely belongs to the views module (but it might be still a common serialization problem).

pingwin4eg’s picture

@mxh There's a separate issue specifically for serialization in Views - #2849674: Complex job in ViewExecutable::unserialize() causes data corruption. And THIS issue might have different source(s) of a problem (as per various reports) - we can't be certain for now. Please move your patch to that issue, and let's discuss it there. And lets return this issue its title.

mxh’s picture

Title: ViewExecutable might break serialization of its own and other data » Fatal error: Call to a member function getFieldStorageDefinition() on array
Component: views.module » field system

As you wish.

mxh’s picture

Status: Needs review » Active

To review and discuss patch from comment #25, please go to #2849674: Complex job in ViewExecutable::unserialize() causes data corruption

patrick.thurmond@gmail.com’s picture

I am having a similar problem except instead of "on Array()" my error is "on null". Definitely a show stopper.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.6 was released on August 2, 2017 and is the final full bugfix release for the Drupal 8.3.x series. Drupal 8.3.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.4.0 on October 4, 2017. (Drupal 8.4.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.4.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.4 was released on January 3, 2018 and is the final full bugfix release for the Drupal 8.4.x series. Drupal 8.4.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.5.0 on March 7, 2018. (Drupal 8.5.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.5.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

techwolf12’s picture

Status: Active » Needs work

Patch doesn't work on 8.5.x

mxh’s picture

Which patch @techwolf12? Approach of #25 is already in 8.5.x, see also #2849674: Complex job in ViewExecutable::unserialize() causes data corruption
Otherwise please provide some details about your occurred problem.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.6 was released on August 1, 2018 and is the final bugfix release for the Drupal 8.5.x series. Drupal 8.5.x will not receive any further development aside from security fixes. Sites should prepare to update to 8.6.0 on September 5, 2018. (Drupal 8.6.0-rc1 is available for testing.)

Bug reports should be targeted against the 8.6.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

drholera’s picture

Any update on this issue? I have the same issue as @pthurmond in #30, error "on null". I think it's related to some broken configs but cannot find with what exactly ones.

Version: 8.6.x-dev » 8.8.x-dev

Drupal 8.6.x will not receive any further development aside from security fixes. Bug reports should be targeted against the 8.8.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.9.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.7 was released on June 3, 2020 and is the final full bugfix release for the Drupal 8.8.x series. Drupal 8.8.x will not receive any further development aside from security fixes. Sites should prepare to update to Drupal 8.9.0 or Drupal 9.0.0 for ongoing support.

Bug reports should be targeted against the 8.9.x-dev branch from now on, and new development or disruptive changes should be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.9.x-dev » 9.2.x-dev

Drupal 8 is end-of-life as of November 17, 2021. There will not be further changes made to Drupal 8. Bugfixes are now made to the 9.3.x and higher branches only. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.2.x-dev » 9.3.x-dev

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.15 was released on June 1st, 2022 and is the final full bugfix release for the Drupal 9.3.x series. Drupal 9.3.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.4.x-dev branch from now on, and new development or disruptive changes should be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

mvonfrie’s picture

I have the same error "on null", but interestingly only for a few random (but always the same) entities of a specific entity type (a group membership). The exact error message is

Call to a member function getFieldStorageDefinition() on null in Drupal\Core\Entity\ContentEntityBase->getEntityKey()

#0 web/core/lib/Drupal/Core/Entity/ContentEntityBase.php(1266): Drupal\Core\Entity\ContentEntityBase->getEntityKey()
#1 web/core/lib/Drupal/Core/Entity/Element/EntityAutocomplete.php(377): Drupal\Core\Entity\ContentEntityBase->label()
#2 web/core/lib/Drupal/Core/Entity/Element/EntityAutocomplete.php(119): Drupal\Core\Entity\Element\EntityAutocomplete::getEntityLabels()

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.9 was released on December 7, 2022 and is the final full bugfix release for the Drupal 9.4.x series. Drupal 9.4.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.5.x-dev branch from now on, and new development or disruptive changes should be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.5.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

quietone’s picture

Status: Needs work » Closed (outdated)
Issue tags: +Bug Smash Initiative

I tested this today on Drupal 11.x, standard install, following the steps in the Issue Summary. I did not get a fatal error when adding an image in the image field. Therefor, I am closing this as outdated.

If you are experiencing this problem on a supported version of Drupal reopen the issue, by setting the status to 'Active', and provide complete steps to reproduce the issue (starting from "Install Drupal core").

Thanks!