FLevelStreamingGCHelper::TrashPackage issue

Summary

During HLOD generation, it seems you can run into a situation where an asset save fails because an FLinkerLoad has an open handle to the file. I believe this is triggered by loading a level instance, unloading it, then loading something that depends on it for HLOD generation.
FWorldPartitionLevelHelper::MoveExternalActorsToLevel calls FLevelStreamingGCHelper::TrashPackage which renames the old package and, later, ResetLoadersForSave looks for any live loaders but it doesn’t find the relevant one because the package has been renamed in TrashPackage. So the file handle remains open when the save is attempted and the write fails.

On 5.7, I fixed this by calling ResetLoaders in TrashPackage, but I see that in 5.8 this has been changed to call TrashObject and there is an ensure in TrashObject asserting that an object should never be trashed during load. Are we doing something wrong to cause this in the first place or was this case not anticipated by the comment in TrashObject?

What Type of Bug are you experiencing?

Editor

Steps to Reproduce

Uncertain what asset setup is required to provoke this. It was quite rare for us and might involve lightly corrupt assets (we’re working on that). But in principle, it should be possible if you trigger the world partition load and then try to save back to the actor before the load is fully complete or cleaned up.

Expected Result

Either it shouldn’t be possible to get into this situation or ResetLoaders should be called in TrashPackage.

Observed Result

Ensure or failed write.

Affects Versions

5.7

Platform(s)

Windows