Problem
When a media entity with a filefield_paths-enabled file field is saved, files are being renamed according to the configured path/name tokens even when active_updating is set to false. This happens every time the entity is saved, regardless of the setting.

Root Cause
In FileFieldPathsProcessFileLegacy.php:73, the condition that determines whether to skip file reprocessing uses property_exists() to detect if the entity has an $original property (representing the pre-save state):

property_exists($entity, 'original') && $entity->original !== NULL
On Drupal 10.x, the $original property is a magic property (accessed via __get()) rather than a real property. property_exists() returns false for magic properties, causing the entire skip condition to fail.

When the skip condition fails, the code proceeds to reprocess and rename the file, ignoring the active_updating: false setting entirely.

Solution
Instead of using property_exists() to detect the original entity, use instanceof ContentEntityInterface on the actual original entity object. This works for both magic properties and real properties:

$original_entity = DeprecationHelper::backwardsCompatibleCall(
\Drupal::VERSION, '11.2.0',
fn(): ?ContentEntityInterface => $entity->getOriginal(),
fn() => $entity->original ?? NULL
);
if ($original_entity instanceof ContentEntityInterface && ...) {
// skip processing
}
This correctly detects whether the entity has a previous version, allowing the skip condition to work as intended when active_updating is false.

CommentFileSizeAuthor
#2 filefield_paths-3616606-2.patch1.63 KBdshields
Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

dshields created an issue. See original summary.

dshields’s picture

StatusFileSize
new1.63 KB

This patch fixes it and makes "Active updating" work as described.

deciphered made their first commit to this issue’s fork.

deciphered’s picture

Status: Needs work » Needs review

Confirmed, and your diagnosis was right down to the mechanism. This is a regression rather than a longstanding bug: 8.x-1.0-rc1 tested the original with isset, and a later cleanup replaced that with property_exists. A content entity keeps its original behind a magic accessor, so property_exists is always false for it, the skip never fires, and the file is renamed on every save. Core 11.2 and newer take the getOriginal branch instead, so the problem stops there. Everything from 10.3 to 11.1 is affected, which is most of what the module supports.

Your patch is the fix, applied with your authorship. I have added two kernel tests on top: one performs the reported sequence of save, change the path pattern, save again, and one is the control with active updating on, so an assertion that the file stayed put cannot pass simply because the hook never ran.

Set to Needs Review. Given the affected range, this should ship in the next release rather than wait.

dshields’s picture

Great - glad to see this will be merged in!

  • deciphered committed 75b9e993 on 8.x-1.x
    test(#3616606): cover the active updating skip path
    

  • deciphered committed b434b121 on 8.x-1.x
    fix(#3616606): detect the original entity without property_exists
    
deciphered’s picture

Status: Needs review » Fixed

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.