When duplicating a blueprint interface, the GraphGuids of the original BP interface's function graphs are unchanged: function graphs across the two BP interfaces now have the same GraphGuid. This is considered working as intended according to comments under [Link Removed]: GraphGuid uniqueness is only guaranteed within the same blueprint.
However, when a blueprint is compiled,
void ConformInterfaceByGUID()
is called whose purpose is to ensure that all interface functions are implemented by the blueprint. The code there assumes that a matching GraphGuid == InterfaceGuid alone is sufficient to conclude that the blueprint's function graph implements a specific interface's function. When a blueprint implements two interfaces that have graphs with the same Guid, this section falsely concludes a blueprint graph implements this interface function, rather than another interface's function with the same GraphGuid. It then concludes the blueprint function graph's name is outdated and renames the graph:
if(InterfaceGraph != nullptr && InterfaceGraph->GraphGuid == BlueprintGraph->InterfaceGuid && InterfaceGraph->GetFName() != BlueprintGraph->GetFName()) { FBlueprintEditorUtils::RenameGraph(BlueprintGraph, InterfaceGraph->GetFName().ToString()); FBlueprintEditorUtils::RefreshGraphNodes(BlueprintGraph); break; }
It also triggers a refresh of all graph nodes.
Side effect 1: non-fatal
If any of those nodes triggers another call to ConformInterfaceByGUID, then this results in a ConformInterfaceByGUID loop: due to the two interfaces fighting over function graphs the ConformInterfaceByGUID will keep making changes, triggering a graph refresh, triggering ConformInterfaceByGUID, and so on. Because some of this behavior is deferred to the next frame (actually, widget paint), this results in non-fatal broken behavior.
Side effect 2: fatal
When a blueprint implements both interfaces and you rename one of the interface functions without compiling it, then compiling the blueprint leads to ConformInterfaceByGUID being recursively called until stack overflow.
Shared repro steps:
Repro steps continued (A) - non-fatal:
Repro steps continued (B) - fatal:
Non-fatal (repro steps A):
> UnrealEditor-Kismet.dll!SMyBlueprint::OnObjectPropertyChanged(UObject * InObject, FPropertyChangedEvent & InPropertyChangedEvent) Line 3119 C++
[Inline Frame] UnrealEditor-Kismet.dll!Invoke(void(SMyBlueprint::*)(UObject *, FPropertyChangedEvent &)) Line 66 C++
[Inline Frame] UnrealEditor-Kismet.dll!UE::Core::Private::Tuple::TTupleBase<TIntegerSequence<unsigned int>>::ApplyAfter(void(SMyBlueprint::*)(UObject *, FPropertyChangedEvent &) &) Line 309 C++
UnrealEditor-Kismet.dll!TBaseRawMethodDelegateInstance<0,SMyBlueprint,void __cdecl(UObject *,FPropertyChangedEvent &),FDefaultDelegateUserPolicy>::ExecuteIfSafe(UObject * <Params_0>, FPropertyChangedEvent & <Params_1>) Line 535 C++
[Inline Frame] UnrealEditor-CoreUObject.dll!TMulticastDelegateBase<FDefaultDelegateUserPolicy>::Broadcast(UObject *) Line 254 C++
[Inline Frame] UnrealEditor-CoreUObject.dll!TMulticastDelegate<void __cdecl(UObject *,FPropertyChangedEvent &),FDefaultDelegateUserPolicy>::Broadcast(UObject *) Line 956 C++
UnrealEditor-CoreUObject.dll!UObject::PostEditChangeProperty(FPropertyChangedEvent & PropertyChangedEvent) Line 443 C++
UnrealEditor-UnrealEd.dll!FBlueprintEditorUtils::MarkBlueprintAsModified(UBlueprint * Blueprint, FPropertyChangedEvent PropertyChangedEvent) Line 1937 C++
UnrealEditor-BlueprintGraph.dll!UEdGraphSchema_K2::ResetPinToAutogeneratedDefaultValue(UEdGraphPin * Pin, bool bCallModifyCallbacks) Line 5359 C++
UnrealEditor-BlueprintGraph.dll!UK2Node::PinConnectionListChanged(UEdGraphPin * Pin) Line 601 C++
UnrealEditor-BlueprintGraph.dll!UK2Node_Knot::PropagatePinTypeFromDirection(bool bFromInput) Line 181 C++
UnrealEditor-BlueprintGraph.dll!UK2Node_Knot::PropagatePinType() Line 122 C++
UnrealEditor-BlueprintGraph.dll!UK2Node_Knot::PostReconstructNode() Line 91 C++
UnrealEditor-BlueprintGraph.dll!UK2Node::ReconstructNode() Line 758 C++
UnrealEditor-BlueprintGraph.dll!UEdGraphSchema_K2::ReconstructNode(UEdGraphNode & TargetNode, bool bIsBatchRequest) Line 4766 C++
UnrealEditor-UnrealEd.dll!FBlueprintEditorUtils::RefreshGraphNodes(const UEdGraph * Graph) Line 763 C++
UnrealEditor-UnrealEd.dll!ConformInterfaceByGUID(const UBlueprint * Blueprint, const FBPInterfaceDescription & CurrentInterfaceDesc) Line 7124 C++
UnrealEditor-UnrealEd.dll!FBlueprintEditorUtils::ConformImplementedInterfaces(UBlueprint * Blueprint) Line 7399 C++
UnrealEditor-Kismet.dll!SMyBlueprint::Refresh() Line 1164 C++
UnrealEditor-SlateCore.dll!SWidget::Paint(const FPaintArgs & Args, const FGeometry & AllottedGeometry, const FSlateRect & MyCullingRect, FSlateWindowElementList & OutDrawElements, int LayerId, const FWidgetStyle & InWidgetStyle, bool bParentEnabled) Line 1483 C++
UnrealEditor-SlateCore.dll!SCompoundWidget::OnPaint(const FPaintArgs & Args, const FGeometry & AllottedGeometry, const FSlateRect & MyCullingRect, FSlateWindowElementList & OutDrawElements, int LayerId, const FWidgetStyle & InWidgetStyle, bool bParentEnabled) Line 46 C++
UnrealEditor-Slate.dll!SBorder::OnPaint(const FPaintArgs & Args, const FGeometry & AllottedGeometry, const FSlateRect & MyCullingRect, FSlateWindowElementList & OutDrawElements, int LayerId, const FWidgetStyle & InWidgetStyle, bool bParentEnabled) Line 129 C++
UnrealEditor-SlateCore.dll!SWidget::Paint(const FPaintArgs & Args, const FGeometry & AllottedGeometry, const FSlateRect & MyCullingRect, FSlateWindowElementList & OutDrawElements, int LayerId, const FWidgetStyle & InWidgetStyle, bool bParentEnabled) Line 1622 C++
Stack overflow (repro steps B):
UnrealEditor-Kismet.dll!FBlueprintEditor::RefreshEditors(ERefreshBlueprintEditorReason::Type Reason) Line 1045 C++
UnrealEditor-Kismet.dll!FBlueprintEditor::OnBlueprintChangedImpl(UBlueprint * InBlueprint, bool bIsJustBeingCompiled) Line 4071 C++
[Inline Frame] UnrealEditor-Kismet.dll!Invoke(void(FBlueprintEditor::*)(UBlueprint *)) Line 66 C++
[Inline Frame] UnrealEditor-Kismet.dll!UE::Core::Private::Tuple::TTupleBase<TIntegerSequence<unsigned int>>::ApplyAfter(void(FBlueprintEditor::*)(UBlueprint *) &) Line 309 C++
UnrealEditor-Kismet.dll!TBaseSPMethodDelegateInstance<0,FBlueprintEditor,1,void __cdecl(UBlueprint *),FDefaultDelegateUserPolicy>::ExecuteIfSafe(UBlueprint * <Params_0>) Line 298 C++
[Inline Frame] UnrealEditor-UnrealEd.dll!TMulticastDelegateBase<FDefaultDelegateUserPolicy>::Broadcast(UBlueprint *) Line 254 C++
UnrealEditor-UnrealEd.dll!TMulticastDelegate<void __cdecl(UBlueprint *),FDefaultDelegateUserPolicy>::Broadcast(UBlueprint * <Params_0>) Line 956 C++
[Inline Frame] UnrealEditor-UnrealEd.dll!UBlueprint::BroadcastChanged() Line 670 C++
UnrealEditor-UnrealEd.dll!FBlueprintEditorUtils::MarkBlueprintAsStructurallyModified(UBlueprint * Blueprint) Line 1884 C++
UnrealEditor-UnrealEd.dll!FBlueprintEditorUtils::RenameGraph(UEdGraph * Graph, const FString & NewNameStr) Line 2717 C++
UnrealEditor-UnrealEd.dll!ConformInterfaceByGUID(const UBlueprint * Blueprint, const FBPInterfaceDescription & CurrentInterfaceDesc) Line 7122 C++
UnrealEditor-UnrealEd.dll!FBlueprintEditorUtils::ConformImplementedInterfaces(UBlueprint * Blueprint) Line 7399 C++
UnrealEditor-Kismet.dll!SMyBlueprint::Refresh() Line 1164 C++
UnrealEditor-Kismet.dll!FBlueprintEditor::RefreshEditors(ERefreshBlueprintEditorReason::Type Reason) Line 1045 C++
UnrealEditor-Kismet.dll!FBlueprintEditor::OnBlueprintChangedImpl(UBlueprint * InBlueprint, bool bIsJustBeingCompiled) Line 4071 C++
[Inline Frame] UnrealEditor-Kismet.dll!Invoke(void(FBlueprintEditor::*)(UBlueprint *)) Line 66 C++
[Inline Frame] UnrealEditor-Kismet.dll!UE::Core::Private::Tuple::TTupleBase<TIntegerSequence<unsigned int>>::ApplyAfter(void(FBlueprintEditor::*)(UBlueprint *) &) Line 309 C++
UnrealEditor-Kismet.dll!TBaseSPMethodDelegateInstance<0,FBlueprintEditor,1,void __cdecl(UBlueprint *),FDefaultDelegateUserPolicy>::ExecuteIfSafe(UBlueprint * <Params_0>) Line 298 C++
[Inline Frame] UnrealEditor-UnrealEd.dll!TMulticastDelegateBase<FDefaultDelegateUserPolicy>::Broadcast(UBlueprint *) Line 254 C++
UnrealEditor-UnrealEd.dll!TMulticastDelegate<void __cdecl(UBlueprint *),FDefaultDelegateUserPolicy>::Broadcast(UBlueprint * <Params_0>) Line 956 C++
[Inline Frame] UnrealEditor-UnrealEd.dll!UBlueprint::BroadcastChanged() Line 670 C++
UnrealEditor-UnrealEd.dll!FBlueprintEditorUtils::MarkBlueprintAsStructurallyModified(UBlueprint * Blueprint) Line 1884 C++
UnrealEditor-UnrealEd.dll!FBlueprintEditorUtils::RenameGraph(UEdGraph * Graph, const FString & NewNameStr) Line 2717 C++
UnrealEditor-UnrealEd.dll!ConformInterfaceByGUID(const UBlueprint * Blueprint, const FBPInterfaceDescription & CurrentInterfaceDesc) Line 7122 C++
UnrealEditor-UnrealEd.dll!FBlueprintEditorUtils::ConformImplementedInterfaces(UBlueprint * Blueprint) Line 7399 C++
UnrealEditor-Kismet.dll!SMyBlueprint::Refresh() Line 1164 C++
UnrealEditor-Kismet.dll!FBlueprintEditor::RefreshEditors(ERefreshBlueprintEditorReason::Type Reason) Line 1045 C++
UnrealEditor-Kismet.dll!FBlueprintEditor::OnBlueprintChangedImpl(UBlueprint * InBlueprint, bool bIsJustBeingCompiled) Line 4071 C++
[Inline Frame] UnrealEditor-Kismet.dll!Invoke(void(FBlueprintEditor::*)(UBlueprint *)) Line 66 C++
[Inline Frame] UnrealEditor-Kismet.dll!UE::Core::Private::Tuple::TTupleBase<TIntegerSequence<unsigned int>>::ApplyAfter(void(FBlueprintEditor::*)(UBlueprint *) &) Line 309 C++
UnrealEditor-Kismet.dll!TBaseSPMethodDelegateInstance<0,FBlueprintEditor,1,void __cdecl(UBlueprint *),FDefaultDelegateUserPolicy>::ExecuteIfSafe(UBlueprint * <Params_0>) Line 298 C++
[Inline Frame] UnrealEditor-UnrealEd.dll!TMulticastDelegateBase<FDefaultDelegateUserPolicy>::Broadcast(UBlueprint *) Line 254 C++
UnrealEditor-UnrealEd.dll!TMulticastDelegate<void __cdecl(UBlueprint *),FDefaultDelegateUserPolicy>::Broadcast(UBlueprint * <Params_0>) Line 956 C++
[Inline Frame] UnrealEditor-UnrealEd.dll!UBlueprint::BroadcastChanged() Line 670 C++
UnrealEditor-UnrealEd.dll!FBlueprintEditorUtils::MarkBlueprintAsStructurallyModified(UBlueprint * Blueprint) Line 1884 C++
UnrealEditor-UnrealEd.dll!FBlueprintEditorUtils::RenameGraph(UEdGraph * Graph, const FString & NewNameStr) Line 2717 C++
UnrealEditor-UnrealEd.dll!ConformInterfaceByGUID(const UBlueprint * Blueprint, const FBPInterfaceDescription & CurrentInterfaceDesc) Line 7122 C++
UnrealEditor-UnrealEd.dll!FBlueprintEditorUtils::ConformImplementedInterfaces(UBlueprint * Blueprint) Line 7399 C++
UnrealEditor-Kismet.dll!SMyBlueprint::Refresh() Line 1164 C++
There's no existing public thread on this issue, so head over to Questions & Answers just mention UE-208678 in the post.
7 |
Component | UE - Gameplay - Blueprint |
---|---|
Affects Versions | 5.1, 5.2, 5.3 |
Target Fix | 5.6 |
Created | Mar 1, 2024 |
---|---|
Updated | Sep 30, 2024 |