Crash when running commandlet because GEditor->Trans is null in GatherObjectReferencersForDeletion

Hello,

We are running a commandlet overnight to delete assets that are not referenced by anything else in a certain folder (these assets are automatically generated by some of our tools, and we have to do regular clean ups).

For the first time (and this has been running for months with no issue), we had a crash overnight when in GatherReferencersForDeletion it arrives to a piece of code where it has to access GEditor->Trans, which is null in commandlet:

// For now, only IsReferenced can output which Property refers to an object and it is required

// when showing the graph dialog of referencers.

// Only called when required and only when references are found, effect of this slower path is expected to be mostly negligible.

// FReferencerFinder::GetAllReferencers could also be refactored a little bit to allow gathering of properties.

if (bOutIsReferenced && bInRequireReferencingProperties && OutMemoryReferences)

{

// determine whether the transaction buffer is the only thing holding a reference to the object

// and if so, offer the user the option to reset the transaction buffer.

GEditor->Trans->DisableObjectSerialization();

bOutIsReferenced = IsReferenced(InObject, GARBAGE_COLLECTION_KEEPFLAGS, EInternalObjectFlags_GarbageCollectionKeepFlags, true, OutMemoryReferences);

if (!bOutIsReferenced)

{

UE_LOG(LogObjectTools, Warning, TEXT(“Detected inconsistencies between reference gathering algorithms. Swiching ‘Editor.UseLegacyGetReferencersForDeletion’ on for the remainder of this editor session.”));

CVarUseLegacyGetReferencersForDeletion->Set(1);

}

GEditor->Trans->EnableObjectSerialization();

}

Protecting the code null checking before those specific codes makes it to work and we can change this internally for us, but putting it here in case other people has had the same issue and a simple null check is not the best approach in this case (as it could have another consequences that we cannot foresee on our side).

Thank you!

Steps to Reproduce
Running a commandlet that ultimately is calling UEditorAssetLibrary::DeleteAsset, and in GatherObjectReferencersForDeletion, arrives to this piece of code:

// For now, only IsReferenced can output which Property refers to an object and it is required

// when showing the graph dialog of referencers.

// Only called when required and only when references are found, effect of this slower path is expected to be mostly negligible.

// FReferencerFinder::GetAllReferencers could also be refactored a little bit to allow gathering of properties.

if (bOutIsReferenced && bInRequireReferencingProperties && OutMemoryReferences)

{

// determine whether the transaction buffer is the only thing holding a reference to the object

// and if so, offer the user the option to reset the transaction buffer.

GEditor->Trans->DisableObjectSerialization();

bOutIsReferenced = IsReferenced(InObject, GARBAGE_COLLECTION_KEEPFLAGS, EInternalObjectFlags_GarbageCollectionKeepFlags, true, OutMemoryReferences);

if (!bOutIsReferenced)

{

UE_LOG(LogObjectTools, Warning, TEXT(“Detected inconsistencies between reference gathering algorithms. Swiching ‘Editor.UseLegacyGetReferencersForDeletion’ on for the remainder of this editor session.”));

CVarUseLegacyGetReferencersForDeletion->Set(1);

}

GEditor->Trans->EnableObjectSerialization();

}

Thanks for reporting this.

Adding null check on GEditor and GEditor->Tran is the right thing to do. It’s what have been done in many other places for the same behavior in the editor.

I will fix this in UE codebase.

Vinz

Thank you to you Vincent!

I saw you already modified the code in main line so I will integrate that in our Engine version.

Thank you again,

Jose