`AWorldDataLayers` gets double initialized if an actor is Rename()d while its level package is still streaming(?) (still has an attached FLinkerLoad).
This happens due to the trick in `::ConditionalFlushAsyncLoadingForLinkers` (called by ::ResetLoaders(UObject*) as part of renaming without REN_ForceNoResetLoaders). `ConditionalFlushAsyncLoadingForLinkers` schedules a max priority async load task for the actor’s package’s linker and then flushes it immediately (in order to flush out any other tasks referring to the linker). If the given package is a level package, this has the side effect of causing a new UWorld to pop into existence (the result of loading the package again). That world gets initialized (via UEditorEngine::InitializeNewlyCreatedInactiveWorld) and eventually initializes its `AWorldDataLayers` via UDataLayerManager.
The trouble is, the new world is pointing to the wrong `AWorldDataLayers`. It is pointing to the one that belongs to the already-in-play level, because during deserialization of the level package it seems to find that the actor (via OFPA?) already exists in memory. Comparing the world pointers of the AWorldDataLayers and the UDataLayerManager near the crash site shows that they belong to two different worlds.
Passing REN_ForceNoResetLoaders to Rename avoids the crash.
Create a new project (I used the first person template).
Create a new “open world” level in that project, but don’t set it as the default level. Set up a data layer in that level that is set to initially loaded.
Place an actor in the open world level that has this code in BeginPlay:
void AMyActor::BeginPlay()
{
Super::BeginPlay();
// in class:
// UPROPERTY(EditAnywhere)
// FSoftObjectPath Asset;
auto Handle = UAssetManager::Get().GetStreamableManager().RequestAsyncLoad({Asset});
Rename(TEXT("ActorHello"));
}
Create a BP subclass of the actor and set its `Asset` property to point to the open world level itself, and then arrange for an actor of that class to be spawned dynamically when entering the open world level (via level script maybe, but NOT by placing an instance in the level). (This is all artificial setup to make sure that the current level package has an attached FLinkerLoad when the Rename occurs… if there’s a more straightforward way, then that should work too.)
4. Add some level script to the _default_ first person level (not the open world level) that opens the open world level shortly after BeginPlay.
5. Run PIE in the default first person level. When being transported to the open world level, there should be a check failure in AWorldDataLayers::InitializeDataLayerRuntimeStates().
This problem was addressed with CL#33136565 which was part of the original branch for 5.5.0. The UObject::Rename method also does not call ResetLoaders as part of the same change. Maybe you missed that code when you updated from 5.4?
You are 100% correct and it turns out we were indeed working off of an older version of UObject::Rename. Apologies for missing that and thanks so much for the quick response! Will look into getting this updated on our end.