Check failing in "FAsyncPackage2::EventDrivenCreateExport" with "ExportObject.TemplateObject->IsA(LoadClass)"

Hi, on our project, we migrated to Unreal 5.7 and when playing a package of our game produced on that version, we get a check that fails under “FAsyncPackage2::EventDrivenCreateExport” for “ExportObject.TemplateObject->IsA(LoadClass)”.

We have 2 classes, A (native class blueprintable and abstract) and B that derives from A (B is done in blueprint).

The message we are getting is something like this:

ExportObject.TemplateObject: ‘Default__A’ is not a child of class: ‘B_C’

The message seems to be inverted compared to how the derivation is really done. Do you have any idea (or ideas to investigate) for what could cause this kind of issue?

Thank you!

[Attachment Removed]

Steps to Reproduce
Please see the description

[Attachment Removed]

This check message was not present in our 5.6.1 branch so it was added in 5.7.

The message was introduced in CL 42444845 and the log was changed in CL 46129101.

But the check was present long before:

check(ExportObject.TemplateObject->IsA(LoadClass));Something happened in our 5.7 integration and messed those asset up

[Attachment Removed]

FYI, I ran a local cook on my computer with “cook.displaymode 4” to see the instigators, and exactly on the assets that are causing this issue, we have something like this in the log:

LogAssetRegistryGenerator: Removing Asset B from the runtime AssetRegistry; it does not exist in the cooked package.

Please note that B in the previous line is define with something like

/PathToB.B

[Attachment Removed]

For the previous message related to removing asset B, it seems the reason it is getting this log is because there’s a non existing on disk object redirector that is already part of the export map (named “Default__B_C_2”, which just by the name doesn’t seem something a user would create manually). This object redirector cannot be found and trying to update object redirectors on the folder containing B results in the UI saying that “Default__B_C_2” has nothing pointing to it, but trying to delete it via the UI does nothing. Resaving B or any dependency pointing to it does nothing and keeps that object redirector in its ExportMap.

[Attachment Removed]

Hello. I’d like to assign your question to the right dev. Before I do that, could you provide the callstack for the crash?

[Attachment Removed]

Hi,

Yes, here’s the callstack for the check failing:

1	P27	FDebug::CheckVerifyFailedImpl2()	AssertionMacros.cpp(745)
2	P27	FAsyncPackage2::EventDrivenCreateExport()	AsyncLoading2.cpp(8708)
3	P27	FAsyncPackage2::Event_ProcessExportBundle()	AsyncLoading2.cpp(7981)
4	P27	FEventLoadNode2::Execute()	AsyncLoading2.cpp(5979)
5	P27	FAsyncLoadEventQueue2::ExecuteSyncLoadEvents()	AsyncLoading2.cpp(6186)
6	P27	FAsyncLoadingThread2::Run()	AsyncLoading2.cpp(10497)
7	P27	FRunnableThreadWin::Run()

[Attachment Removed]

Hi Jean-Philippe,

I’m curious if those assets have been modified/resaved since your upgrade to 5.7?

If they were modified, is it possible to roll them back to their original working state and cook with 5.7 to see if the issue is still present or gone.

Just trying to see if the bug is in the cooker or potentially the save as it doesn’t seem to be a loader bug from your description.

Thanks

Danny

[Attachment Removed]

Hi Danny,

The direct assets and the ones directly depending on them have not been resaved on our Perforce depot since moving to 5.7. The resaving tests I was mentionning were done locally or prior to submitting them to our Perforce depot by the build system by using a “preflight” system to test our changes before submitting them. Everything cooks well and there are no warnings or errors, except for when using “cook.displaymode 4” which displayed some issues related to what I previously described. The issue happens when running a package at the end.

[Attachment Removed]

Hi Jean-Philippe,

I think the next step will be to get our hands on a repro. Do you think you can come up with something on your side, maybe recreating the same kind of asset you currently have in a smaller repro project that gives you this issue that you could send to us?

Thanks

Danny

[Attachment Removed]

Hi Danny,

This might be complicated to provide in this case to be honest, since the problem is unclear for exactly which data seems to cause the issue. From what I am seeing, asset “B” that I was talking about seems to already have “Default__B_C_2” in its “ExportMap” in “FLinkerLoad::SerializeExportMap” when simply loading our project in the editor under 5.7. So I assume that perhaps something was serialized under 5.6 that was working well, but now it tries to create an object redirector that exists only in memory which in the ends leads to the issue I was saying dring the cook process. I tried to put a breakpoint to see if this “ExportMap” is being written to, but it doesn’t seem to be the case, so it seems to only be loaded. Right now, since we are using data coming from another project, I simply deleted it to get rid of the issue so that people can play a package produced in 5.7, but since the cause of the issue is unclear, I’m worried it might come back again later when trying to generate that kind of data again.

[Attachment Removed]

Hi Jean-Philippe,

Someone had the same problem not long ago and the conclusion was that the check wasn’t at the right spot and should be moved out of the branch as an else clause of the outer if ((ObjectLoadFlags & RF_ClassDefaultObject) != 0). We’re probably going to apply this fix for 5.8.

Let me know if that works out for you.

Thanks

Danny

[Attachment Removed]

Hi Danny,

I modified the code like you said in your previous reply and when running a package, the check is not longer trigerring, so in this case it is fine. However, soon after when loading the package, we fail elsewhere for the related data causing us issues in the following function:

FAsyncPackage2::EventDrivenSerializeExport

For the check:

checkObject(Object, Object->HasAllFlags(RF_NeedPostLoad | RF_WasLoaded));The value we have for our object “B” is the following:

Object = Default__B_C
ObjectFlags	RF_Public | RF_Transactional | RF_ClassDefaultObject | RF_ArchetypeObject | RF_WasLoaded | RF_LoadCompleted (2621497)	EObjectFlags

Here’s the callstack for this failing check:

>	P27-Win64-DebugGame.exe!FAsyncPackage2::EventDrivenSerializeExport(const FAsyncPackageHeaderData & Header, int LocalExportIndex, FExportArchive * Ar) Line 8953	C++
 	P27-Win64-DebugGame.exe!FAsyncPackage2::Event_ProcessExportBundle(FAsyncLoadingThreadState2 & ThreadState, FAsyncPackage2 * Package, int InExportBundleIndex) Line 8051	C++
 	P27-Win64-DebugGame.exe!FEventLoadNode2::Execute(FAsyncLoadingThreadState2 & ThreadState) Line 6001	C++
 	P27-Win64-DebugGame.exe!FAsyncLoadEventQueue2::PopAndExecute(FAsyncLoadingThreadState2 & ThreadState) Line 6176	C++
 	P27-Win64-DebugGame.exe!FAsyncLoadingThread2::Run() Line 10570	C++
 	P27-Win64-DebugGame.exe!FRunnableThreadWin::Run() Line 159	C++
 	P27-Win64-DebugGame.exe!FRunnableThreadWin::GuardedRun() Line 71	C++
 	kernel32.dll!BaseThreadInitThunk()	Unknown
 	ntdll.dll!RtlUserThreadStart()	Unknown

Please note that I also have 2 others objects of the same type that are failing, I will call them “C” and “D”. During the cook process (with “cook.displaymode 4”), these 3 objects display the message I was saying earlier (you can replace B by the full path to B, C or D, ie, /PathToB.B), which like I said earlier might be the reason why it fails in the package in the end, because it seems something is not added to it:

LogAssetRegistryGenerator: Removing Asset B from the runtime AssetRegistry; it does not exist in the cooked package.If I pass these failing checks, then I get an ensure for the class D in:

UBlueprintGeneratedClass::InitPropertiesFromCustomList

[2026.05.07-12.56.13:459][  1]LogOutputDevice: Error: Ensure condition failed: bCustomPropertyListForPostConstructionInitialized [File:D:\p4\p27_dev_main\Engine\Source\Runtime\Engine\Private\BlueprintGeneratedClass.cpp] [Line: 1256] 
Custom Property List Not Initialized for /PathToD.D_C

The “cleaned” callstack leading to this is in the form:

 	P27-Win64-DebugGame.exe!UBlueprintGeneratedClass::InitPropertiesFromCustomList::__l3::<lambda_1>::operator()() Line 1256	C++
>	P27-Win64-DebugGame.exe!UBlueprintGeneratedClass::InitPropertiesFromCustomList(unsigned char * DataPtr, const unsigned char * DefaultDataPtr) Line 1256	C++
 	P27-Win64-DebugGame.exe!FObjectInitializer::InitProperties(UObject * Obj, UClass * DefaultsClass, UObject * DefaultData, bool bCopyTransientsFromClassDefaults) Line 4716	C++
 	P27-Win64-DebugGame.exe!FObjectInitializer::PostConstructInit() Line 4372	C++
 	P27-Win64-DebugGame.exe!FObjectInitializer::~FObjectInitializer() Line 4242	C++
 	P27-Win64-DebugGame.exe!StaticConstructObject_Internal(const FStaticConstructObjectParameters & Params) Line 4989	C++
 	P27-Win64-DebugGame.exe!NewObject<A>(UObject * Outer, const UClass * Class, FName Name, EObjectFlags Flags, UObject * Template, bool bCopyTransientsFromClassDefaults, FObjectInstancingGraph * InInstanceGraph, UPackage * InExternalPackage) Line 1913	C++
 
Below this point we are in a BeginPlay on an actor and on a component of this actor in its BeginPlay, we create an object of class D which derives from A.

[Attachment Removed]

Hi Jean-Phillippe,

Clearly you have multiple problems stacking on top of one another here and which needs to investigated separately. I understand trying to obfuscate project information but that can make it harder to diagnose the subtility in the problem in some case. I’m going to give you a few things to double check, but if you still require help beyond that, it might be worthwhile to convert to a private question so you can provide a bit more information that might be sensitive. Beyond the template check, the next thing to understand is the asset registry log in question. What are B, C, D mentioned here? The BPGC, the UBlueprint object, the CDO, something else? This log means that when saving that specific package that asset was filtered out of the result for some reason, probably meaning it wouldn’t be available at runtime. This could be something possible for example if the native class from which this object derives isn’t present in the runtime target, or it could happen for other reasons… if you are having running issues with those assets, resolving the cooking issue probably comes first in this case. In term of the issue you end up getting when deserializing the CDO is that something has already called PostLoad on it and it happened prior to the object being deserialized. This can happen if you have code conditional post loading objects but usually required some sort of circular dependency in the loading request to result in that. I’d expect that the custom property list issue following that is also similarly related.

Hopefully, these are some hints to try and resolve the issue. As I said if you still require assistance, request the question to be made private so you can share more information.

Thank you!

Francis

[Attachment Removed]

Hi Francis,

Thank you for your answer. Yes, I was already investigating the cook process when I was talking about the message from the asset registry. Like I said, since then, I deleted the related data since it was not used for our project so for now we no longer have the issue, but I suspect that when we repopulate that data, the issue might come back if it was not related to data conversion between versions. If we ever get this issue again, I will investigate it more then.

Thank you!

[Attachment Removed]