Problem/Motivation

While playing with a view, i may have clicked multiple times on the remove button for a "representative node" fields. The view modification page was not working anymore and i reloaded the page.

At reload, the page showed multiple error, and i can not edit the view anymore.

First warning:
Warning : Undefined array key "tid_representative" dans Drupal\views\Plugin\views\HandlerBase->getEntityType() (ligne 709 de web/core/modules/views/src/Plugin/views/HandlerBase.php).

Second warning:
Warning : Trying to access array offset on value of type null dans Drupal\views\Plugin\views\HandlerBase->getEntityType() (ligne 710 de /app/web/core/modules/views/src/Plugin/views/HandlerBase.php).

Error:
InvalidArgumentException: A valid cache entry key is required. Use getAll() to get all table data. in Drupal\views\ViewsData->get() (line 140 of core/modules/views/src/ViewsData.php).

Steps to reproduce

1. In a view, add a "Taxonomy term: Representative node" relationship (like described by View Taxonomy Term and hide empty terms.
2. In the same view, add filters on the representative node content.
3. Remove the representative node relationship without removing the filters.

Proposed resolution

In HandlerBase.php, rewrite the getEntityType() method like this:

  /**
   * {@inheritdoc}
   */
  public function getEntityType() {
    // If the user has configured a relationship on the handler take that into
    // account.
    $relationship_key = $this->options['relationship'] ?? '';
    if ($relationship = $this->displayHandler->getOption('relationships')[$relationship_key] ?? NULL) {
      $table_data = $this->getViewsData()->get($relationship['table']);
      $views_data = $this->getViewsData()->get($table_data[$relationship['field']]['relationship']['base']);
    }
    else {
      $views_data = $this->getViewsData()->get($this->view->storage->get('base_table'));
    }

    if (isset($views_data['table']['entity type'])) {
      return $views_data['table']['entity type'];
    }
    else {
      throw new \Exception("No entity type for field {$this->options['id']} on view {$this->view->storage->id()}");
    }
  }

Remaining tasks

Make a better rewrite of getEntityType(), to have only one $views_data failsafe instead of the two introduce by the given solution.

User interface changes

None.

API changes

None.

Data model changes

None.

Release notes snippet

Fix error when editing view with filters from a missing representative node relationship.

Issue fork drupal-3275276

Command icon 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

landure created an issue. See original summary.

larowlan’s picture

Title: Unable to enter views edition form » Removing a relationship that is used by a filter can prevent access to editing a view
Priority: Normal » Major

Thanks for reporting

Anything that lets you cause a fatal error from the UI we class as major

lendude’s picture

Status: Active » Postponed (maintainer needs more info)

I tried to reproduce this, but can't.

Steps I took:
* Clean Umami install
* Create taxonomy View
* Add 'Representative node' relationship with default settings
* Add Filter on node content title using the relationship, set to contains 'choc'
* Remove relationship
* Error shown in UI: The filter criterion Content: Title uses a relationship that has been removed.

So nothing break for me, are there any specific steps I'm missing here that would cause this to break?

landure’s picture

The break was a edge case I think, and short of using hacks, it is difficult to reproduce.

The issue stays valid, since if the break occurs, there is no way to recover. The fix seems painless and has no impact on functionnality.

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.

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.

guypaddock’s picture

Version: 9.5.x-dev » 10.0.x-dev
Status: Postponed (maintainer needs more info) » Active

Repro:

  1. I created a paragraphs type.
  2. I created a content type that has a paragraphs field that can reference items of the paragraphs type I created in step 1.
  3. I created a new view of paragraphs.
  4. I added a required relationship to the view that links paragraphs to content that references the paragraph.
  5. I added a content type filer to the view that uses the relationship added in step 4.
  6. I deleted the relationship that I had added in step 4.

At this point, the Views UI stopped responding -- I couldn't even get the dialog that I was using to edit/delete the relationship to close. Upon refreshing the edit form for the View, I got a WSOD with these stack traces:

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

InvalidArgumentException: A valid cache entry key is required. Use getAll() to get all table data. in Drupal\views\ViewsData->get() (line 140 of core/modules/views/src/ViewsData.php).
Drupal\views\Plugin\views\HandlerBase->getEntityType() (Line: 93)
Drupal\views\Plugin\views\filter\Bundle->init(Object, Object, Array) (Line: 904)
Drupal\views\Plugin\views\display\DisplayPluginBase->getHandlers('filter') (Line: 2532)
Drupal\views\Plugin\views\display\DisplayPluginBase->validate() (Line: 2127)
Drupal\views\ViewExecutable->validate() (Line: 128)
Drupal\views_ui\ViewFormBase->getDisplayTabs(Object) (Line: 49)
Drupal\views_ui\ViewFormBase->prepareEntity() (Line: 125)
Drupal\Core\Entity\EntityForm->init(Object) (Line: 26)
Drupal\views_ui\ViewFormBase->init(Object) (Line: 96)
Drupal\Core\Entity\EntityForm->buildForm(Array, Object) (Line: 41)
Drupal\views_ui\ViewFormBase->buildForm(Array, Object)
call_user_func_array(Array, Array) (Line: 534)
Drupal\Core\Form\FormBuilder->retrieveForm('view_edit_form', Object) (Line: 281)
Drupal\Core\Form\FormBuilder->buildForm(Object, Object) (Line: 48)
Drupal\Core\Entity\EntityFormBuilder->getForm(Object, 'edit', Array) (Line: 230)
Drupal\views_ui\Controller\ViewsUIController->edit(Object, NULL)
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: 163)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 74)
Symfony\Component\HttpKernel\HttpKernel->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: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\StackedHttpKernel->handle(Object, 1, 1) (Line: 681)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Warning: Undefined array key "reverse__node__field_poll_choices" in Drupal\views\Plugin\views\HandlerBase->getEntityType() (line 720 of core/modules/views/src/Plugin/views/HandlerBase.php).
Drupal\views\Plugin\views\HandlerBase->getEntityType() (Line: 93)
Drupal\views\Plugin\views\filter\Bundle->init(Object, Object, Array) (Line: 904)
Drupal\views\Plugin\views\display\DisplayPluginBase->getHandlers('filter') (Line: 2532)
Drupal\views\Plugin\views\display\DisplayPluginBase->validate() (Line: 2127)
Drupal\views\ViewExecutable->validate() (Line: 128)
Drupal\views_ui\ViewFormBase->getDisplayTabs(Object) (Line: 49)
Drupal\views_ui\ViewFormBase->prepareEntity() (Line: 125)
Drupal\Core\Entity\EntityForm->init(Object) (Line: 26)
Drupal\views_ui\ViewFormBase->init(Object) (Line: 96)
Drupal\Core\Entity\EntityForm->buildForm(Array, Object) (Line: 41)
Drupal\views_ui\ViewFormBase->buildForm(Array, Object)
call_user_func_array(Array, Array) (Line: 534)
Drupal\Core\Form\FormBuilder->retrieveForm('view_edit_form', Object) (Line: 281)
Drupal\Core\Form\FormBuilder->buildForm(Object, Object) (Line: 48)
Drupal\Core\Entity\EntityFormBuilder->getForm(Object, 'edit', Array) (Line: 230)
Drupal\views_ui\Controller\ViewsUIController->edit(Object, NULL)
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: 163)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 74)
Symfony\Component\HttpKernel\HttpKernel->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: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\StackedHttpKernel->handle(Object, 1, 1) (Line: 681)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Warning: Trying to access array offset on value of type null in Drupal\views\Plugin\views\HandlerBase->getEntityType() (line 721 of core/modules/views/src/Plugin/views/HandlerBase.php).
Drupal\views\Plugin\views\HandlerBase->getEntityType() (Line: 93)
Drupal\views\Plugin\views\filter\Bundle->init(Object, Object, Array) (Line: 904)
Drupal\views\Plugin\views\display\DisplayPluginBase->getHandlers('filter') (Line: 2532)
Drupal\views\Plugin\views\display\DisplayPluginBase->validate() (Line: 2127)
Drupal\views\ViewExecutable->validate() (Line: 128)
Drupal\views_ui\ViewFormBase->getDisplayTabs(Object) (Line: 49)
Drupal\views_ui\ViewFormBase->prepareEntity() (Line: 125)
Drupal\Core\Entity\EntityForm->init(Object) (Line: 26)
Drupal\views_ui\ViewFormBase->init(Object) (Line: 96)
Drupal\Core\Entity\EntityForm->buildForm(Array, Object) (Line: 41)
Drupal\views_ui\ViewFormBase->buildForm(Array, Object)
call_user_func_array(Array, Array) (Line: 534)
Drupal\Core\Form\FormBuilder->retrieveForm('view_edit_form', Object) (Line: 281)
Drupal\Core\Form\FormBuilder->buildForm(Object, Object) (Line: 48)
Drupal\Core\Entity\EntityFormBuilder->getForm(Object, 'edit', Array) (Line: 230)
Drupal\views_ui\Controller\ViewsUIController->edit(Object, NULL)
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: 163)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 74)
Symfony\Component\HttpKernel\HttpKernel->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: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\StackedHttpKernel->handle(Object, 1, 1) (Line: 681)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
alain dg’s picture

Had the same on a user view with reationship to "content authored" whose (a) title is displayed as field + (b) node values are used as filter.
Deleted the relationship by mistake and now cannot use the view Ui anymore.
Note that I didn't save the view, but nevertheless the view UI for that particular view throws the error message below, even after clearing cache or changing browser.

Error message:

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

InvalidArgumentException: A valid cache entry key is required. Use getAll() to get all table data. in Drupal\views\ViewsData->get() (line 140 of core/modules/views/src/ViewsData.php).
Drupal\views\Plugin\views\HandlerBase->getEntityType() (Line: 88)
Drupal\views\Plugin\views\filter\Bundle->init(Object, Object, Array) (Line: 895)
Drupal\views\Plugin\views\display\DisplayPluginBase->getHandlers('filter') (Line: 2523)
Drupal\views\Plugin\views\display\DisplayPluginBase->validate() (Line: 532)
Drupal\views\Plugin\views\display\PathPluginBase->validate() (Line: 509)
Drupal\views\Plugin\views\display\Page->validate() (Line: 2112)
Drupal\views\ViewExecutable->validate() (Line: 128)
Drupal\views_ui\ViewFormBase->getDisplayTabs(Object) (Line: 49)
Drupal\views_ui\ViewFormBase->prepareEntity() (Line: 125)
Drupal\Core\Entity\EntityForm->init(Object) (Line: 26)
Drupal\views_ui\ViewFormBase->init(Object) (Line: 96)
Drupal\Core\Entity\EntityForm->buildForm(Array, Object) (Line: 41)
Drupal\views_ui\ViewFormBase->buildForm(Array, Object)
call_user_func_array(Array, Array) (Line: 531)
Drupal\Core\Form\FormBuilder->retrieveForm('view_edit_form', Object) (Line: 278)
Drupal\Core\Form\FormBuilder->buildForm(Object, Object) (Line: 48)
Drupal\Core\Entity\EntityFormBuilder->getForm(Object, 'edit', Array) (Line: 230)
Drupal\views_ui\Controller\ViewsUIController->edit(Object, NULL)
call_user_func_array(Array, Array) (Line: 123)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() (Line: 564)
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: 158)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 80)
Symfony\Component\HttpKernel\HttpKernel->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: 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: 708)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
merlin06’s picture

Preserving the original code

  /**
   * {@inheritdoc}
   */
  public function getEntityType() {
    // If the user has configured a relationship on the handler take that into
    // account.
    if (!empty($this->options['relationship']) && $this->options['relationship'] != 'none') {
      $relationships = $this->displayHandler->getOption('relationships');
      if(isset($relationships[$this->options['relationship']])) {
        $relationship = $relationships[$this->options['relationship']];
        $table_data = $this->getViewsData()->get($relationship['table']);
        $views_data = $this->getViewsData()->get($table_data[$relationship['field']]['relationship']['base']);
      }
      else {
        $views_data = $this->getViewsData()->get($this->view->storage->get('base_table'));
      }
    }
    else {
      $views_data = $this->getViewsData()->get($this->view->storage->get('base_table'));
    }

    if (isset($views_data['table']['entity type'])) {
      return $views_data['table']['entity type'];
    }
    else {
      throw new \Exception("No entity type for field {$this->options['id']} on view {$this->view->storage->id()}");
    }
  }
merlin06’s picture

Issue summary: View changes
merlin06’s picture

Credit for this snippet goes to https://www.drupal.org/u/bradtreloar from https://www.drupal.org/australian-competition-and-consumer-commission-accc and I modified the issue description with it.

$relationships = $this->displayHandler->getOption('relationships');
if(isset($relationships[$this->options['relationship']])) {
  $relationship = $relationships[$this->options['relationship']];
  $table_data = $this->getViewsData()->get($relationship['table']);
  $views_data = $this->getViewsData()->get($table_data[$relationship['field']]['relationship']['base']);
}
else {
  $views_data = $this->getViewsData()->get($this->view->storage->get('base_table'));
}
merlin06’s picture

StatusFileSize
new1.59 KB

Rolled a patch.

merlin06’s picture

StatusFileSize
new1.23 KB

Patch 12 is incorrect.
Rolled patch 13 against original file.

prabuela’s picture

Assigned: Unassigned » prabuela
prabuela’s picture

Assigned: prabuela » Unassigned
StatusFileSize
new1.45 KB
merlin06’s picture

_pratik_’s picture

StatusFileSize
new1.23 KB

#15 patch contains error, #16 is corrupted.
Try this.
Thanks

merlin06’s picture

Issue summary: View changes
StatusFileSize
new1.02 KB

This patch restores the original else branch that is still required.

else {
  $views_data = $this->getViewsData()->get($this->view->storage->get('base_table'));
}
lendude’s picture

Status: Active » Postponed (maintainer needs more info)
Issue tags: +Need tests, +Needs steps to reproduce

Tried the steps in #8 on a clean Drupal Umami install, couldn't reproduce. Might miss some steps to break?

Didn't try the steps in #7 since those require a contrib module. Can we get some steps to reproduce this with just core? Or an automated test that shows where this breaks? Without clear steps its really hard to see if the proposed fix is the right way to go.

Version: 10.0.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.

smustgrave’s picture

Status: Postponed (maintainer needs more info) » Closed (outdated)

Since there hasn't been a follow up in 2 years going to close out. If still a valid bug please re-open.

eduardo morales alberti’s picture

It is possible that the error is related to the PHP serializer. In our case, we use igbinary. We will try to change it to PHP, and see if the problem is gone

todea’s picture

We encountered this issue in Drupal 10.6.9. Patch #18 worked, allowing us to cancel the view edits (which hadn't been saved yet) and restore previous version.

duozersk’s picture

Status: Closed (outdated) » Needs review

The issue is still present with Drupal 11.4.11, the patch in #18 applies cleanly through cweagans/composer-patches and then I was able to edit the broken view with incorrectly removed relationship.

smustgrave’s picture

Status: Needs review » Needs work

Issue tags would still be relevant then so putting in NW

mortona2k’s picture

The problem here is that HandlerBase->getEntityType() is getting stuck trying to figure out the entity type of a removed relationship.

The trigger is the content type/bundle filter. Set up a view that uses it with a relationship, save, then delete the relationship.

#18 is an appropriate fix, falling back to the view's entity type when the relationship type is missing.

Another way would be to update the relationship selection on the filter when the relationship is removed.

#2988983: Removing a relationship to an entity reference field can break a View was created after this one, and mixes this up with another problem that appears similar. That one breaks when the relationship is to a table that doesn't have an entity type. Similar problem, but the handling is a little different.

mortona2k’s picture

Status: Needs work » Needs review

!MR17639 includes the fix from #18, an extra check in HandlerBase to load the entity type from the current table, and a test.

This may fix most if not all issues in #2988983: Removing a relationship to an entity reference field can break a View.

This MR was generated with claude after studying both issues.

chrisdarke’s picture

On 11.4.10: After I had built a view with 2 levels of entity reference (Main Content > Sub Content, SubSub Content), and used the deepest level entity in a filter (SubSubContent.address country code external filter), I then went to delete that SubSub Content relationship forgetting I had a filter set, and it threw everything into the error state as described. Clearing the temp bin, and even `drush cim` didn't fix it.

Patched with patch #18 and immediately was able to edit the view and cancel the changes.

RTBC, but I haven't had a chance to check the MR, and was just trying to get unstuck so I am going to leave it in 'Needs Review' for someone to review the MR.