Usage check prevents media being deleted due to thumbnail

Created on 28 July 2025, about 1 month ago

Problem/Motivation

The module doesn't do what it's supposed to do, because all media have at least 2 usages, one of which is the thumbnail from Drupal core.

The thumbnail field is defined in core/modules/media/src/Entity/Media::baseFieldDefinitions():

$fields['thumbnail'] = BaseFieldDefinition::create('image')
  ->setLabel(t('Thumbnail'))
  ->setDescription(t('The thumbnail of the media item.'))
  ->setRevisionable(TRUE)
  ->setTranslatable(TRUE)
  ->setDisplayOptions('view', [
    'type' => 'image',
    'weight' => 5,
    'label' => 'hidden',
    'settings' => [
      'image_style' => 'thumbnail',
    ],
  ])
  ->setDisplayConfigurable('view', TRUE)
  ->setReadOnly(TRUE);

It seems that during postSave() hooks the thumbnail gets created and it gets marked as a usage of the file.

Steps to reproduce

  1. Set up media with an image media type.
  2. Add a media image.
  3. Check the file_usage table, it has 2 usages.
  4. Try to delete the file, it says "The file attached to this media is used in 1 other place and will be retained.".

Proposed resolution

I do not know. The issue is here in MediaDeleteForm.php:

$usages = $this->usageResolver->getFileUsages($file);
if ($usages > 1) {
  return $build + [
    'cannot_delete' => [
      '#markup' => new PluralTranslatableMarkup($usages - 1, 'The file attached to this media is used in 1 other place and will be retained.', 'The file attached to this media is used in @count other places and will be retained.'),
    ],
  ];
}

I assume the fact it was done this way is because for some people this works. The only way I can think to fix it for my own site is to patch this to check for 2 instead of 1 (just for this site). But there should be a more generic solution which is aware of automatic usages that media always have on a particular site.

Remaining tasks

User interface changes

API changes

Data model changes

πŸ› Bug report
Status

Active

Version

1.3

Component

Code

Created by

πŸ‡¬πŸ‡§United Kingdom Rob230

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

Comments & Activities

  • Issue created by @Rob230
  • πŸ‡¬πŸ‡§United Kingdom Rob230

    On this site there are multiple ways of adding images. Images which come from an external integration (via a custom entity browser) only have 1 usage, whereas images added with the Drupal file upload have 2.

    I suspect it might be this thumbnail in the image upload field which creates the extra usage:

    This is using the "Image (focal point)" widget from the focal_point module, but I changed it to the core "Image" widget and it still gets 2 usages - it still creates a thumbnail to the left of the filename after uploading.

  • πŸ‡¬πŸ‡§United Kingdom Rob230

    The frustrating thing is there is no way to tell where a file is used - it's just a scalar count, without any information about where the usage is.

    So I have no way to tell whether a file is in use or not. The thumbnail on the image upload page is not a real use! Is this a core bug?

  • πŸ‡¬πŸ‡§United Kingdom Rob230

    This function Media::loadThumbnail() adds the target_id of the file into the thumbnail field, and then the postSave() on the field will add a usage. I can't see any way to prevent this from happening.

  • πŸ‡¬πŸ‡§United Kingdom Rob230

    I've been barking up completely the wrong tree. All of the above is a red herring. The fact it has 2 usages in the file_usage table is not what the media_file_delete module uses to determine it. Those usages actually get reduced down by CoreFileUsageResolver::getFileUsages():

    public function getFileUsages(FileInterface $file) : int {
      return array_reduce($this->fileUsage->listUsage($file), function (int $count, array $module_usage) {
        return $count + array_reduce($module_usage, function (int $object_count, array $object_usage) {
            return $object_count + count($object_usage);
        }, 0);
      }, 0);
    }
    

    The reason there are 2 usages is because media_file_delete combines the file usage with the entity usage in ChainedFileUsageResolver::getFileUsages():

    public function getFileUsages(FileInterface $file): int {
      $usage = 0;
      foreach ($this->getSortedResolvers() as $resolver) {
        assert($resolver instanceof FileUsageResolverInterface);
        $usage += $resolver->getFileUsages($file);
      }
      return $usage;
    }
    

    So I am not sure whether this is a bug or not. I still think the module doesn't do what it's supposed to out of the box if you combine it with entity_usage, but I'm not sure how to fix that or if it should be. I suppose it needs to realise if one of the usages is the media entity that the file usage is also on, then that's the same usage and it's safe to delete.

  • πŸ‡¬πŸ‡§United Kingdom Rob230

    Logically, I think we can always subtract 1 from the usage if the media_file_delete_entity_usage is enabled. You can assume 1 usage will always be from the file itself, so the usages on the media entity are all that's relevant. This can be checked in MediaDeleteForm.php.

  • πŸ‡¬πŸ‡§United Kingdom Rob230
  • πŸ‡¬πŸ‡§United Kingdom Rob230

    I've rewritten the issue description with the actual problem.

    Here is my proposed solution which I think should work for all scenarios. It excludes the media entity which is trying to be deleted from the count, because by definition we don't care about that usage if that's the thing we want to delete.

  • πŸ‡¬πŸ‡§United Kingdom Rob230

    This should work even if the media_file_delete_entity_usage module is not enabled.

  • πŸ‡¬πŸ‡§United Kingdom Rob230
  • πŸ‡ΊπŸ‡ΈUnited States segx Las Vegas, NV

    I'm experiencing a similar issue in D-10.4.8, and patch #9 doesn't seem to resolve the issue. I have both 'Media File Delete' and 'Media File Delete - Entity Usage' enabled. I'm not sure if this helps, but the problem may be more of a cache issue. At deletion, the file isn't deleted because it recognizes itself. After deleting the media item, I immediately check in Files and it still shows a usage. Then I clear cache and the usage becomes 0.

Production build 0.71.5 2024