We’re hitting this ensure when opening a specific asset, or when opening a level referencing the asset
void UBlueprintGeneratedClass::InitPropertiesFromCustomList(uint8* DataPtr, const uint8* DefaultDataPtr)
{
// autortfm: we've introduced a conditional lock here because while running under autortfm, we
// only want to take this lock if necessary (if FAsyncLoadingThreadSettings says we're multithreaded)
// if not running under autortfm, IsClosed is false and we will always lock without querying whether
// we are running multithreaded.
UE::TConditionalScopeLock SerializeAndPostLoadLock(
SerializeAndPostLoadCritical,
(!AutoRTFM::IsClosed()) || FAsyncLoadingThreadSettings::Get().bAsyncLoadingThreadEnabled);
if (GBlueprintNativePropertyInitFastPathDisabled
|| !ensureMsgf(bCustomPropertyListForPostConstructionInitialized, TEXT("Custom Property List Not Initialized for %s"), *GetPathNameSafe(this))) // Something went wrong, probably a race condition
We don’t have any divergences in this code. I found another thread regarding this issue, but it mentions that somehow renaming the asset fixed it. We have a large data set so that may not be viable for us if this is widespread.
Would you be able to create a small sample project with the asset reproducing the issue?
Do you know if it’s only the one asset or something it depends on, if so could you attempt to rename the asset having the problem? That way we can know if the problem is widespread or fixed in the same way.
Are there any extra / different logs when opening the asset or is it the same as the other thread?
Another thing you could try is rebuilding and reimporting the asset to see if the issue persists.
We’re also hitting this on a different project. the component in question that is failing to load is a actor component. renaming it did not work. Any suggestions for debugging/fixing this would be helpful.
I may have found a “fix” for this - if I comment out this line in FLinkerLoad::DeferExportCreation in BlueprintSupport.cpp the assert no longer fires
if (!bAlreadyResolvingExport || GetLoaderType() != ELoaderType::ZenLoader)
{
ForceRegenerateClass(LoadClass);
}
The asset that asserts is one that does have circular dependencies. I noticed that in 5.5 we were triggering the ForceRegenerateClass call, which is what led to the caching of bCustomPropertyListForPostConstructionInitialized.
From what I can see, disabling this check isn’t causing any detrimental effects. I believe something in this change is breaking assets that have cyclical dependencies. It would be good if Epic could take a closer look at it and let us know if this is an appropriate workaround or if there’s a better solution
I can confirm SerializeDefaultObject, therefore UpdateCustomPropertyListForPostConstruction for those objects is called after InitPropertiesFromCustomList, which seems like the wrong order. I’ll dig deeper into finding the race condition.
We’re also seeing this ensure. In our case, it happens whenever any asset is saved when it’s trying to construct our custom validators to process the saved asset. This only happens on the first time save in an editor session and fires once for reach custom validator.
Thank you for all the updates and information. I went ahead and pushed the case up to Epic, along with a summary of all the input to assist with further troubleshooting. That being said their offices are closed until 7/14 and will get back to you as soon as possible.
Thank you all for your patience. In the meantime, if you come across any additional information, please feel free to share.
Hey folks, apologies for the slow response time. We’re almost caught up on EPS cases again so this will improve.
Having read up on the thread, Luke if I understand your finding correctly by commenting out the condition
if (!bAlreadyResolvingExport || GetLoaderType() != ELoaderType::ZenLoader)which causes ForceRegenerateClass to be called, you no longer run into the ensure? So for the asset that trips the ensure ForceRegenerateClass() was called in 5.5, but is skipped in 5.6, is that right?
Since you’ve already spent time comparing 5.5 and 5.6 behavior, would you mind sharing the 5.5 and 5.6 callstacks of when FLinkerLoad::DeferExportCreation is entered, as well as when in 5.6 the bCustomPropertyListForPostConstructionInitialized ensure fails?
For the folks from other studios running into the failing ensure, can you also share the callstack of the failing ensure?
So far, I believe the issue is triggered by the presence of cyclical dependencies. If the callstack contains calls to LoadPackageInternal, please annotate it with which asset is being loaded (anonymize if needed, like BP_SomeParentClassA, etc). That will give valuable info despite not being able to isolate this into a small repro project. I’ll collect some more data and then pass on to a suitable engine dev. Thanks everyone!
This out-of-order call sequence is likely the source of the issue (i.e. assuming it’s due to circular dependency on load)
> I can confirm SerializeDefaultObject, therefore UpdateCustomPropertyListForPostConstruction for those objects is called after InitPropertiesFromCustomList, which seems like the wrong order. I’ll dig deeper into finding the race condition.
Unfortunately these can be difficult to diagnose/fix w/o a sample project with content that demonstrates the issue, because speculative fixes or disabling code tends to introduce unintentional side effects elsewhere, and it’s not likely that sort of workaround patching will be included in an official release.
There are a couple things that can be explored/investigated:
1) Set ‘bp.NativePropertyInitFastPathDisabled 1’ to disable the initialization fast path for testing. If the problem goes away, then it’s likely related to that path and what’s being discussed here.
2) Try and eliminate the circular dependency if possible and if it can be identified. Sometimes this can involve moving code/logic from Blueprint into a native C++ parent class.
FWIW, it is also possible to ship with bp.NativePropertyInitFastPathDisabled 1 (or you can just set GBlueprintNativePropertyInitFastPathDisabled to ‘true’ in BlueprintGeneratedClass.cpp - unfortunately it is not exposed directly as a project setting). We default to keeping the fast path enabled to give all projects the potential cost benefits by default, but in some affected projects this should be “fine” to turn off, as it just means there will be some native property initialization redundancy when instancing Blueprint types that won’t otherwise be eliminated. So there might be a net cost negative to overall load and/or spawn times, but depending on how many e.g. Actor-based Blueprint classes there are, it might also not be that significant. Doing A/B perf testing might be worth exploring in that case.
I don’t think we’re going to be able to make a sample project - this blueprint inherits from a native c++ type we’ve created. I’ve tried asset validation, recompiling, and renaming the asset - none worked. I don’t see any useful info in the logs either.
Do we know what this assert means? What’s the impact of it?
This error means that the custom property list used to initialize Blueprint properties had something that prevented it from being initialized.
That could likely happen due to an incomplete blueprint compilation, asset corruption, the native class missing something, or a race condition when async loading.
The impact is that properties may not initialize properly, missing / default property values on instances of the bp, or a broken asset.
If rebuilding from scratch doesn’t work, i.e. deleting folders Saved/, Intermediate/, DerivedDataCache/ - it might be worth double checking the C++ native class for any issues with the class’s reflection setup.
Some things to check: UCLASS(Blueprintable), GENERATED_BODY(), Super(ObjectInitializer) in the constructor, correct use of UPROPERTY().
If we’re unable to still find anything I can escalate this to Epic.
Unfortunately we haven’t found anything in the native class setup that looks wrong - I also tried deleting the DDC and saved/intermediate and still repro’ed the issue
I have the callstack included as an attachment to my reply for reference. I haven’t done any comparisons of 5.5 vs 5.6 behavior so I can’t provide those details.
Ensure condition failed: bCustomPropertyListForPostConstructionInitialized [File:./Runtime/Engine/Private/BlueprintGeneratedClass.cpp] [Line: 1242]
LogPlayLevel: UAT: Custom Property List Not Initialized for /Game/RTS_Camera/Blueprints/BPC_MobileInput.BPC_MobileInput_C
Anybody managed to fix this issue?
I’m experiencing this exact same error with a actor component from a Fab plugin I purchased and have been working at trying to fix it. It can be easily replicated on both 5.6 and 5.7 with fresh projects and this “Ultimate RTS Camera” plugin setup.