UnrealEditor-CoreUObject.dll!UObjectBaseUtility::MarkAsGarbage() Line 178
UnrealEditor-CoreUObject.dll!StaticConstructObject_Internal(const FStaticConstructObjectParameters & Params) Line 4984
UnrealEditor-NiagaraEditor.dll!NewObject(UObject *) Line 1927
UnrealEditor-NiagaraEditor.dll!UNiagaraNodeAssignment::GenerateScript() Line 346
UnrealEditor-NiagaraEditor.dll!UNiagaraNodeAssignment::RefreshFromExternalChanges() Line 87
UnrealEditor-NiagaraEditor.dll!UNiagaraScriptSource::RefreshFromExternalChanges() Line 168
UnrealEditor-Niagara.dll!FNiagaraEmitterHandle::SetIsEnabled(bool bInIsEnabled, UNiagaraSystem & InOwnerSystem, bool bRecompileIfChanged) Line 148
I’d be curious to know what the repro steps are to trigger this. Are you only able to do it in your project, or does this happen also in a new empty project? Does it happen every time, or randomly? If you can send repro steps for a new empty project, I’d be able to see exactly what’s happening on my side and help fix it.
But to guess the problem, it might be that the parent particle system got added to the root set, which then could triggers this crash. Usually, assets that get loaded very early on, during engine initialization, get added to the root set. For example, if you have a C++ class that hard-loads an asset in its constructor via ConstructorHelpers. That is a recipe for a bunch of problems, using PROPERTY class member variables and setting their value in a derived Blueprint asset is the correct method.
Or it might be hard referenced by some other system that early initializes.
Try putting a breakpoint into UNiagaraScript’s C++ constructor and see when it gets created. It might be some other class also, like UNiagaraSystem. There will always be at least the C++ CDO constructed very early on, so ignore that one, but anything else in early engine initialization might indicate the problem.
I cannot test this in a new project, since we cannot pin point an exact repro.
Randomly, but once it starts happening, it can happen multiple times in a short time. Feels like some data is saved in a problematic state. I am counting on this to attach a debugger the next time a user has the issue.
The repro steps a roughly:
enabling an emitter while PIE is running (with said emitter).
Applying a material (though last time we saw that was in 5.5).
I tried what you suggested without finding any system or script that loads suspiciously early, but will try again more carefully when I have time. I will report back my findings.
Objects being added in the rootset wrongfully did not occur to me (although the error is about that ). This is useful, I’ll see if I can add checks to spot the error early on.
Since it’s hard to repro, let’s focus on how to catch it when it happens.
You could enable the “prompt for remote debugging” to catch it in a debugger
UE can ask for remote debugging just before crashing / asserting which would help here.
You can turn it on via command line when launching the process: -PromptRemoteDebug or -PromptRemoteDebugEnsure.
And also via config, so everyone in the team gets it. In DefaultEngine.ini:
[Engine.ErrorHandling]
bPromptForRemoteDebugging=True
and / or
bPromptForRemoteDebugOnEnsure=True
Then, when someone catches the crash and that popup shows up, you can get a programmer to walk over or remotely debug their process. See more here: Advanced Debugging in Unreal Engine | Tutorial
If you don’t want it to happen for every crash or ensure, you can also enable it just before that problematic function by putting this before the function where it fails:
You can also use FPlatformMisc::SetShouldPromptForRemoteDebugOnEnsure(true) for ensures. Like, for example, if you were to add a custom ensure close to the problematic function that crashes when the object is a part of the root set.