Skip to content

[UE 5.8] RemoveOrphanedNodes: GetObjectsWithOuter port inverts bIncludeNestedObjects, widening the orphan sweep #389

Description

@fcarreiro

Hi there! Bug found by Claude when updating to a 5.8 compatible version.

Summary

The UE 5.8 port of UFlowGraph::RemoveOrphanedNodes() replaces the deprecated
bool bIncludeNestedObjects overload of GetObjectsWithOuter with
EGetObjectsFlags::IncludeNestedObjects. That inverts the original behaviour: the
pre-5.8 branch passes false, but IncludeNestedObjects means true. The
equivalent flag is EGetObjectsFlags::None.

Version

  • Flow v2.3-5.8 (release asset Flow_v2.3_5.8.zip)
  • Unreal Engine 5.8, Windows, MSVC 14.44.35222

Location

Source/FlowEditor/Private/Graph/FlowGraph.cpp, in UFlowGraph::RemoveOrphanedNodes()
(around lines 421-428 in the release build):

TArray<UObject*> AllInners;
constexpr bool bIncludeNestedObjects = false;

#if ENGINE_MAJOR_VERSION == 5 && ENGINE_MINOR_VERSION < 8
	GetObjectsWithOuter(GetOuter(), AllInners, bIncludeNestedObjects);
#else
	GetObjectsWithOuter(GetOuter(), AllInners, EGetObjectsFlags::IncludeNestedObjects);
#endif

Why this is wrong

From Engine/Source/Runtime/CoreUObject/Public/UObject/FindObjectFlags.h:

enum class EGetObjectsFlags
{
	None = 0,

	/** If specified, then objects whose outers directly or indirectly have Outer as an outer are included, these are the nested objects */
	IncludeNestedObjects = 1 << 0,
	...
};

EGetObjectsFlags::None is the drop-in replacement for bIncludeNestedObjects == false.
Passing IncludeNestedObjects is the replacement for true. So on 5.8 the function now
collects objects nested indirectly under the asset's outer, where every prior engine
version collected only direct children.

Impact

AllInners feeds the orphan sweep immediately below, and the only filter is
CanRemoveNestedObject(), which excludes only UEdGraphNode, UEdGraph and
UEdGraphSchema:

for (auto InnerIt = AllInners.CreateConstIterator(); InnerIt; ++InnerIt)
{
	UObject* TestObject = *InnerIt;
	if (!NodeInstances.Contains(TestObject) && CanRemoveNestedObject(TestObject))
	{
		OnNodeInstanceRemoved(TestObject);
		TestObject->SetFlags(RF_Transient);
		TestObject->Rename(nullptr, GetTransientPackage(), REN_DontCreateRedirectors | REN_NonTransactional);
	}
}

Objects nested below a Flow node (AddOns, Data Pin property objects, and other
sub-objects) are not in NodeInstances, and are not UEdGraph* types, so on 5.8 they
now become candidates for being marked RF_Transient and renamed into the transient
package. On earlier versions they were never enumerated at all.

I found this by inspection while migrating a project from 5.7 to 5.8, and have not yet
reproduced concrete asset corruption — but the behavioural change is unambiguous, and it
lands in the Data Pins / AddOns area that 2.2 and 2.3 refactored.

Suggested fix

 #if ENGINE_MAJOR_VERSION == 5 && ENGINE_MINOR_VERSION < 8
 	GetObjectsWithOuter(GetOuter(), AllInners, bIncludeNestedObjects);
 #else
-	GetObjectsWithOuter(GetOuter(), AllInners, EGetObjectsFlags::IncludeNestedObjects);
+	GetObjectsWithOuter(GetOuter(), AllInners, EGetObjectsFlags::None);
 #endif

Since the flag is now a compile-time constant on both sides, the #if could also be
collapsed by mapping the bool once, which would prevent the two branches drifting again.

Note

The other 5.8 ports in this release look correct — both Rename call sites
(FlowGraph.cpp and FlowGraphEditor.cpp) simply drop the now-redundant
REN_ForceNoResetLoaders, and the DiffControl.h Private->Internal include-path
guards are fine. This appears to be the only inverted one.

Still present on 5.x (default branch) as of 2026-08-31. Introduced by
5b6c1222d92fecff448d6f5923574f9a59542743 ("addressed UE 5.8 API deprecations",
2026-05-13), which replaced the bool call with the flag call. The most recent commit to
touch this file is 1f5ecd9c (2026-06-03), so it has not been revisited since.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions