Change record status: 
Introduced in version: 
1.2.6
Description: 

A custom PHPStan rule is now shipped with the module to catch a common integration mistake at static analysis time rather than at runtime.

Classes that use BuildFieldTrait and call any of its entity-building methods (buildEntities(), buildReferencedEntities(), buildEntitiesWithViewModes(), buildReferencedEntitiesWithViewModes()) must declare a protected CacheableMetadata $cacheableMetadata property. Without it, those methods fail at runtime because they internally access $this->cacheableMetadata to track cache dependencies.

The new PHPStan rule detects this missing declaration during static analysis, so you get a clear error message instead of a cryptic runtime failure.

How it works

The rule is automatically registered via PHPStan's extension-installer. If your project uses phpstan/extension-installer (recommended), no configuration is needed — just run PHPStan as usual.

If you don't use extension-installer, add this to your phpstan.neon:

includes:
    - web/modules/contrib/pluggable_entity_view_builder/phpstan-extension.neon

Example error

Classes using BuildFieldTrait must declare a protected $cacheableMetadata
property of type \Drupal\Core\Cache\CacheableMetadata.
💡 Declare "protected \Drupal\Core\Cache\CacheableMetadata $cacheableMetadata;"
   in the class body.

Before (triggers error)

use Drupal\pluggable_entity_view_builder\BuildFieldTrait;

class NodeViewBuilder extends EntityViewBuilderPluginAbstract {

  use BuildFieldTrait;

  public function build(array $build, EntityInterface $entity): array {
    $build['field_image'] = $this->buildEntities($entity->get('field_image')->referencedEntities());
    return $build;
  }

}

After (correct)

use Drupal\Core\Cache\CacheableMetadata;
use Drupal\pluggable_entity_view_builder\BuildFieldTrait;

class NodeViewBuilder extends EntityViewBuilderPluginAbstract {

  use BuildFieldTrait;

  protected CacheableMetadata $cacheableMetadata;

  public function build(array $build, EntityInterface $entity): array {
    $build['field_image'] = $this->buildEntities($entity->get('field_image')->referencedEntities());
    return $build;
  }

}

Note: If your class extends EntityViewBuilderPluginAbstract, the property is already declared there — no action needed. This rule primarily catches cases where BuildFieldTrait is used in standalone classes without the abstract base.

Impacts: 
Site builders, administrators, editors
Module developers