Drupal 10 and 11 – How to Check if an Entity is Referenced Before Deleting

In Drupal 10 and Drupal 11, entities (like nodes, taxonomy terms, users, or custom entities) are often linked together using entity reference fields.

But what happens if you try to delete an entity that is already referenced by another piece of content?

  • Example: A taxonomy term used in multiple articles.
  • If deleted directly, it can break relationships or leave empty references.

That’s why it’s a best practice to check if an entity is referenced before deleting.

Why Should We Check for References?

  • Prevent data loss.
  • Maintain clean relationships between entities.
  • Avoid broken content where a reference is missing.

Using the EntityReference API

Drupal provides ways to check referencing entities. The idea is:

  1. Load the entity you want to delete.
  2. Use the entity_field.manager service to check if other entities reference it.

Example: Checking if a Taxonomy Term is Referenced

Let’s say you have a taxonomy term, and before deleting it, you want to see if any nodes reference it.

use Drupal\taxonomy\Entity\Term;
use Drupal\Core\Entity\EntityTypeManagerInterface;

/**
 * Check if a taxonomy term is referenced.
 */
function is_term_referenced(Term $term, EntityTypeManagerInterface $entity_type_manager) {
  $storage = $entity_type_manager->getStorage('node');
  
  // Find nodes where this term is referenced.
  $query = $storage->getQuery()
    ->condition('status', 1) // Only published nodes
    ->condition('field_tags.target_id', $term->id()); // Assuming 'field_tags' is your reference field
  
  $nids = $query->execute();
  
  return !empty($nids); // TRUE if term is referenced
}

If TRUE → Term is referenced, don’t delete.
If FALSE → Safe to delete.

Generic Method for Any Entity

If you don’t know which entities might reference it, you can check all entity reference fields.

use Drupal\Core\Entity\EntityFieldManagerInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;

/**
 * Check if an entity is referenced anywhere.
 */
function is_entity_referenced($entity, EntityFieldManagerInterface $field_manager, EntityTypeManagerInterface $entity_type_manager) {
  $entity_type = $entity->getEntityTypeId();
  $entity_id = $entity->id();

  // Get all fields from all entities.
  foreach ($field_manager->getFieldMapByFieldType('entity_reference') as $ref_entity_type => $fields) {
    foreach ($fields as $field_name => $info) {
      if ($info['settings']['target_type'] === $entity_type) {
        $storage = $entity_type_manager->getStorage($ref_entity_type);
        $query = $storage->getQuery()
          ->condition($field_name . '.target_id', $entity_id);

        if ($query->execute()) {
          return TRUE; // Entity is referenced
        }
      }
    }
  }
  return FALSE; // Not referenced
}

This works for any entity (nodes, taxonomy, users, custom entities).

  • se hook_entity_predelete() to prevent deletion of referenced entities.
  • Provide a user-friendly error message instead of just blocking.
  • Log references for debugging if needed.

Example hook:

/**
 * Implements hook_ENTITY_TYPE_predelete().
 */
function mymodule_taxonomy_term_predelete(array $entities) {
  foreach ($entities as $term) {
    if (is_term_referenced($term, \Drupal::entityTypeManager())) {
      throw new \Drupal\Core\Entity\EntityStorageException(
        t('The term %name is still referenced and cannot be deleted.', ['%name' => $term->label()])
      );
    }
  }
}

Conclusion

In Drupal 10 and 11, always check if an entity is referenced before deleting.

  • Use entity queries for specific fields.
  • Or use a generic entity reference scan for all entities.
  • Prevent deletion inside hook_entity_predelete() to keep your data safe.

This way, you maintain clean, error-free relationships between content.