A class inheriting from a Blueprint class with a ChildActorComponent may have an invalid Outer.

Creating a class that inherits from a Blueprint class containing ChildActorComponent and then executing LiveCoding in that state may cause an invalid ChildActorComponent to be cloned during a ChildActorComponent::Serialize call from a worker thread. This can trigger the check(IsInAsyncLoadingThread()) call within AActor::PostInitProperties.

I believe the root cause is that the value of the Blueprint class inheriting from the Blueprint class with the ChildActorComponent is unexpected.

Once the Blueprint class reaches this state, the issue will not be resolved until the ChildActorTemplate’s Outer is correctly modified and the file is saved.

Do you have any information regarding this issue?

    if (IsTemplate())
    {
      // If we are a template and are not pointing at a component we own we'll need to fix that
      if (ChildActorTemplate->GetOuter() != this)
      {
        const FString TemplateName = FString::Printf(TEXT("%s_%s_CAT"), *GetName(), *ChildActorClass->GetName());
        if (UObject* ExistingTemplate = StaticFindObject(nullptr, this, *TemplateName))
        {
          ChildActorTemplate = CastChecked<AActor>(ExistingTemplate);
        }
        else
        {
          ChildActorTemplate = CastChecked<AActor>(StaticDuplicateObject(ChildActorTemplate, this, *TemplateName)); //< ★here
        }
      }
    }

再現手順

  1. Create a new Blueprint class with a ChildActorComponent. (Let’s call it A for now)
  2. Create a new Blueprint class with A as its parent class. (Let’s call it B.)
  3. At this point, the `OuterPrivate` of the `ChildActorTemplate` within B’s `ChildActorComponent` may point to A’s `ChildActorComponent` rather than B’s own `ChildActorComponent`.
  4. Furthermore, when live coding is executed in this state, it attempts to correctly modify the Outer of B’s ChildActorTemplate within ChildActorComponent::Serialize during a call from the worker thread.
  5. This may cause check(IsInAsyncLoadingThread()) to be called within AActor::PostInitProperties.

Hello [mention removed]​,

I tried reproducing this in an blank project in 5.6 following the steps you described: created a BP parent class with a ChildActorComponent, derived a child Blueprint and performed operations like renaming components, toggling the Child Actor Class and running Live Coding reloads while the derived Blueprint was open.

So far I haven’t been able to trigger the check(IsInAsyncLoadingThread()) call inside AActor::PostInitProperties.

If possible, could you share a minimal repro project or a step sequence that consistently reproduces the issue on your end?

Also could you confirm, what type of changes were compiled via Live Coding when the check was triggered on your end.

Best,

Francisco

Hello [mention removed]​,

Thanks again for the report. Following up on this, I was able to consistently reproduce the issue both in a UE 5.6 source build and also in a recent source build from Main (CL 48526824). The behavior matches what you described: during Live Coding, the ChildActorComponent template in the derived Blueprint is serialized on a worker thread, and the template fix-up path leads to a thread check in AActor::PostInitProperties, which causes the editor to crash.

I’ve registered an internal bug report so this can be tracked: Unreal Engine Issues and Bug Tracker (UE\-355951\). You will be able to follow its status once the ticket becomes public.

As a temporary workaround, when working with a derived Blueprint that includes a ChildActorComponent in this scenario, I recommend refraining from using Live Coding after engine source edits. Instead, please rebuild the Engine module from your IDE and relaunch the editor.

Please let me know if you need anything else regarding this case, otherwise I’ll proceed with closing the case.

Best,

Francisco

Thank you for your confirmation. [mention removed]​

We have rechecked the reproduction steps and added points 2, 4, and 6 (indicated in bold).

  1. Create a new Blueprint class with a ChildActorComponent. (Let’s call it A for now)
  2. Set the ChildActorClass of the ChildActorComponent added to A to Actor.
  3. Create a new Blueprint class with A as its parent class. (Let’s call it B.)
  4. Save the created A and B in the Blueprint Editor, and keep the Blueprint Editor open just in case.
  5. At this point, the `OuterPrivate` of the `ChildActorTemplate` within B’s `ChildActorComponent` may point to A’s `ChildActorComponent` rather than B’s own `ChildActorComponent`.
  6. Please add or remove comment lines in ChildActorComponent.cpp, Actor.cpp, and ActorComponent.cpp.
  7. Furthermore, when live coding is executed in this state, it attempts to correctly modify the Outer of B’s ChildActorTemplate within ChildActorComponent::Serialize during a call from the worker thread.
  8. This may cause check(IsInAsyncLoadingThread()) to be called within AActor::PostInitProperties.

In Step 5, it appears certain that ChildActorTemplate->OuterPrivate within the ChildActorComponent will take on an unintended value. (This has been confirmed by adding processing to ChildActorComponent::PreSave()).

However, it remains unclear whether this check always triggers during live coding.

Currently, it occurs when adding or removing comment lines across multiple cpp files. (It does not occur with a single file alone.)

Thank you for your confirmation.

Hello [mention removed]​,

Thank you for the additional details. With your updated repro steps I was able to reproduce the issue locally in a source build of UE 5.6. I also confirmed that the crash occurs during Live Coding after adding comments to ChildActorComponent.cpp, Actor.cpp, and ActorComponent.cpp, matching your description.

I’ll continue investigating this behavior and follow up with any additional findings or next steps soon.

Best,

Francisco