Problem/Motivation
I am importing .csv data that includes references to another entity. I am using the following setup and no tampers
“Reference by: Title
Autocreate entities: No”
Here is error I am getting on import when I have an entity with the title that does not exist
An AJAX HTTP error occurred.
HTTP Result Code: 500
Debugging information follows.
Path: /batch?id=3846&op=do_nojs&op=do
StatusText: error
ResponseText: The website encountered an unexpected error. Try again later.Error: Attempt to assign property "hash" on null in Drupal\feeds\Feeds\Target\EntityReference->setTarget() (line 127 of modules/contrib/feeds/src/Feeds/Target/EntityReference.php). Drupal\feeds\Feeds\Processor\EntityProcessorBase->map() (Line: 302)
Drupal\feeds\Feeds\Processor\EntityProcessorBase->process() (Line: 128)
Drupal\feeds\EventSubscriber\LazySubscriber->Drupal\feeds\EventSubscriber\{closure}()
call_user_func() (Line: 111)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch() (Line: 41)
Drupal\feeds\FeedsExecutable->dispatchEvent() (Line: 267)
Drupal\feeds\FeedsExecutable->doProcess() (Line: 111)
Drupal\feeds\FeedsExecutable->processItem() (Line: 297)
_batch_process() (Line: 139)
_batch_do() (Line: 95)
_batch_page() (Line: 52)
Drupal\system\Controller\BatchController->batchPage()
call_user_func_array() (Line: 123)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() (Line: 637)
Drupal\Core\Render\Renderer->executeInRenderContext() (Line: 121)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext() (Line: 97)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() (Line: 181)
Symfony\Component\HttpKernel\HttpKernel->handleRaw() (Line: 76)
Symfony\Component\HttpKernel\HttpKernel->handle() (Line: 53)
Drupal\Core\StackMiddleware\Session->handle() (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle() (Line: 28)
Drupal\Core\StackMiddleware\ContentLength->handle() (Line: 32)
Drupal\big_pipe\StackMiddleware\ContentLength->handle() (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle() (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle() (Line: 36)
Drupal\Core\StackMiddleware\AjaxPageState->handle() (Line: 51)
Drupal\Core\StackMiddleware\StackedHttpKernel->handle() (Line: 741)
Drupal\Core\DrupalKernel->handle() (Line: 19)
This happens only when:
- More than one feed is used to update the same content.
- Mapping to Feeds Item is defined earlier than mapping to Entity Reference.
- The source provides a value for the entity reference field, but Feeds cannot find an existing entity for it.
It is caused by a bug in the FeedsItem mapping target. What the target currently does when it receives a value to import (for example a 'guid' value), it writes that to the first row of the feeds_item field and it destroys all other rows on the feeds_item field. Not only this may set a 'guid' value on the wrong row, the feeds_item field may also loose a reference to the current feed.
This results into the fatal error later on the EntityReference mapping target. The current code expects that the feeds_item field contains a reference to the current feed, but if that value was destroyed earlier by the FeedsItem mapping target then this is not the case and it results into the reported error.
Steps to reproduce
- Create two feeds that will update the same content.
- For the feed type that the second feed uses, add mappings to the feeds_item field and mapping to an entity reference field. Add mapping to the feeds_item field first, so that it occurs before the mapping to the entity reference field.
- For the entity reference value in the second feed, use a value for which no entity can be found.
- Import the first feed.
- Import the second feed.
Proposed resolution
When setting a value for the feeds_item field, the FeedsItem mapping target should look for the row that contains a reference to the current feed and update that row. It should not assume that the first row should be updated.
Remaining tasks
Issue fork feeds-3583799
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 #2
irinaz commentedComment #5
megachrizI've provided a fix for this issue and updated the issue summary.
The failure was caused by that the FeedsItem mapping target always set values on the first row of a feeds_item field and then destroys all other rows. When you are using multiple feeds to update the same content this could cause that the row that references the current feed gets deleted. The EntityReference mapping target blindly assumes that the feeds_item field always contains a reference to the current feed and if that is not the case in results into the reported error.
The fix is that the FeedsItem mapping target now searches first for the row that references the current feed and it updates that one. And it no longer destroys the other rows.
Comment #6
benstallings commentedClaude Code says:
1. Minor: comment typo in test
Line 166 — "for at the least one" should be "for at least one".
2. Consider: what happens when getEntityTarget() returns a non-null non-EntityInterface value?
At FeedsItem.php:67, you guard with if (!$entity_target instanceof EntityInterface). Looking at FieldTargetBase::getEntityTarget(), it can return void (implicit null) when the langcode doesn't match. The instanceof check is fine, but it silently swallows the case — the old code would have errored. If this should never happen during normal operation, a log or exception might be more debuggable than a silent return.
The code itself is solid and ready to go!