Bug: EntityViewBuilderPluginAbstract::build() silently discards cache metadata added in buildFull()
>>> [!note] Migrated issue
<!-- Drupal.org comment -->
<!-- Migrated from issue #3577874. -->
Reported by: [balagan](https://www.drupal.org/user/1230072)
Related to !54
>>>
<p>Problem</p>
<p>EntityViewBuilderPluginAbstract::build() in 1.2.4 wraps the plugin's build method with a $this->cacheableMetadata pattern:</p>
<pre>$this->cacheableMetadata = CacheableMetadata::createFromRenderArray($build);<br>$build = $this->$method($build, $entity);<br>$this->cacheableMetadata->applyTo($build);<br>return $build;</pre><p>
CacheableMetadata::applyTo() replaces (not merges) the render array's #cache data:</p>
<pre>public function applyTo(array &$build) {<br> $build['#cache']['contexts'] = $this->cacheContexts; // replaces<br> $build['#cache']['tags'] = $this->cacheTags; // replaces<br> $build['#cache']['max-age'] = $this->cacheMaxAge; // replaces<br>}</pre><p>
Because $this->cacheableMetadata is created before buildFull() runs, any cache contexts, tags or max-age values added directly to $build['#cache'] inside buildFull() are silently overwritten when applyTo() is called afterward.</p>
<p>Example — cache context wiped:</p>
<pre>public function buildFull(array $build, NodeInterface $entity) {<br> // ...<br> $build['#cache']['contexts'][] = 'og_membership_state'; // ← lost after applyTo()<br> return $build;<br>}</pre><p>
Impact</p>
<p>The entity render cache is keyed before buildFull() runs (via Drupal's #pre_render pipeline). With cache contexts wiped by applyTo(), the render cache no longer varies by those contexts, causing stale cached content to be served to users who should see different content. This is a regression from 1.1.19 where the return value of buildFull() was used as-is.</p>
<p>Fix</p>
<p>applyTo() should be replaced with an additive merge. One option:</p>
<pre>$this->cacheableMetadata = CacheableMetadata::createFromRenderArray($build);<br>$build = $this->$method($build, $entity);<br>// Merge accumulated BuildFieldTrait metadata INTO the build without overwriting<br>// cache metadata already set by the build method itself.<br>$after = CacheableMetadata::createFromRenderArray($build);<br>$after->merge($this->cacheableMetadata)->applyTo($build);<br>return $build;</pre><p>
Alternatively, change applyTo() usage to addCacheableDependency() or use Cache::mergeTags() / Cache::mergeContexts() directly.</p>
issue