Possible regression due to introduction of variation cache

Created on 5 January 2024, about 1 year ago

Problem/Motivation

Since Drupal 10.2 we're seeing the following error:

LogicException: The complete set of cache contexts for a variation cache item must contain all of the initial cache contexts, missing: languages:language_interface, theme. in Drupal\Core\Cache\VariationCache->set() (line 47 of core/lib/Drupal/Core/Cache/VariationCache.php).

This is caused by the following code:

public function MYMODULE_node_view(array &$build, NodeInterface $node, EntityViewDisplayInterface $display, string $view_mode): void {
  $cache = CacheableMetadata::createFromObject($display);
  $cache->addCacheableDependency($node);
  // Do stuff ...
  $cache->applyTo($build);
}

Prior to 10.2 this worked as expected, and the X-Drupal-Cache-Contexts header includes both the languages:language_interface and theme contexts. These must have been added later in the render pipeline at some point later, as they aren't present in the CacheableMetadata in the hook above. Note that they are present if we change it to CacheableMetadata::createFromRenderArray($build).

If I remove the code that detects missing contexts and throws the LogicException then the page loads correctly and the X-Drupal-Cache-Contexts header contains the expected contexts.

Steps to reproduce

Proposed resolution

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

🐛 Bug report
Status

Active

Version

11.0 🔥

Component
Cache 

Last updated about 9 hours ago

Created by

🇦🇺Australia mstrelan

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

  • Issue created by @mstrelan
  • 🇨🇭Switzerland berdir Switzerland

    To summarize the slack discussion we just had. that those cache contexts are there on the page level isn't really relevant, they must always be there on each element that's cached separately.

    The code is wrong as it replaces existing cacheability info from $build, which could cause very weird caching issues if the node is rendered in a different theme or isn't invalidated properly for cache tags and contexts that get lost.

    And, if those two are the only things it adds, it can be removed entirely because both display and the node are already considered cache dependencies.

    So the change is that subtle, hard to track down cache bugs are replaced with an exception.

  • Status changed to Closed: works as designed about 1 year ago
  • 🇳🇱Netherlands casey

    I think we should either merge any existing cache metadata on the renderable, like the patch in #5,

    or throw an exception if the CacheableMetadata removes any existing cache metadata when applied to a renderable (diffing the new resulting #cache with the old existing ##cache)

  • 🇺🇸United States moshe weitzman Boston, MA

    I agree that applyTo() is a gotcha. The merge or the Exception sound good to me.

  • Status changed to Needs review 8 months ago
  • 🇳🇱Netherlands timohuisman Leiden, Netherlands

    It sounds like we can reopen this issue as a feature request? The patch in #5 contains the suggested merge. I think the merge would be the most logical solution, because the name applyTo doesn't suggest that it overwrites the existing data.

  • Status changed to Needs work 8 months ago
  • The Needs Review Queue Bot tested this issue.

    While you are making the above changes, we recommend that you convert this patch to a merge request . Merge requests are preferred over patches. Be sure to hide the old patch files as well. (Converting an issue to a merge request without other contributions to the issue will not receive credit.)

  • 🇳🇱Netherlands timohuisman Leiden, Netherlands

    timohuisman changed the visibility of the branch 3412444-make-cacheablemetadataapplyto-merge to hidden.

  • Merge request !8409merge existing CacheableMetadata in applyTo → (Open) created by timohuisman
  • Status changed to Needs review 8 months ago
  • 🇳🇱Netherlands timohuisman Leiden, Netherlands
  • 🇳🇱Netherlands timohuisman Leiden, Netherlands
  • Pipeline finished with Failed
    8 months ago
    Total: 514s
    #198655
  • Pipeline finished with Failed
    8 months ago
    Total: 168s
    #198700
  • Pipeline finished with Failed
    8 months ago
    Total: 516s
    #198712
  • Pipeline finished with Failed
    8 months ago
    Total: 195s
    #198770
  • Pipeline finished with Failed
    8 months ago
    Total: 546s
    #198776
  • Pipeline finished with Failed
    8 months ago
    Total: 514s
    #198802
  • Pipeline finished with Success
    8 months ago
    Total: 547s
    #198811
  • Status changed to Needs work 8 months ago
  • 🇺🇸United States smustgrave

    Can the issue summary be completed please.

    Have not reviewed but ran test-only feature which confirms test coverage.

  • 🇮🇳India nitinpatil

    Thanks, patch #5 works for me.

  • 🇸🇪Sweden erik.erskine

    I've updated the issue summary to attempt to better describe this feature request.

  • Status changed to Needs review about 1 month ago
  • 🇺🇸United States smustgrave

    // @todo determine if we want to use Cache::mergeContexts() here.
    // Note that we cannot use Cache::mergeContexts() here,

    This comment doesn't make much sense to me. Should it be updated ?

  • 🇺🇸United States smustgrave

    Comment still doesn't really make sense. Think at minimum the todo part should be removed. Leaving in review for other thoughts

    If you are another contributor eager to jump in, please allow the previous poster at least 48 hours to respond to feedback first, so they have the opportunity to finish what they started!

Production build 0.71.5 2024