Consider an array property that can be edited in the StateTree editor. This can be a State Parameter or an exposed property of a Condition or Task, for example. Each element of the array can be bound to a Property Function, such as "Math – Float – Add", that has its own inputs. When the user attempts to change the value of one of these Property Function inputs, an ensure() is triggered inside function UE::StateTree::PropertyHelpers::DispatchPostEditToNodes().
Inside DispatchPostEditToNodes(), all current bindings are accessible in "EditorData.EditorBindings.PropertyBindings", where the "TargetPropertyPath" for an array element contains path segments roughly equivalent to "ArrayName[ArrayIndex]". On the other hand, the function incrementally builds a "TargetPath" to search for, which for an array element becomes equivalent to "ArrayName[ArrayIndex].ArrayName" (note the duplicated array name segment). As a result, the search performed to assign "FoundBinding" does not yield any match, and the ensure() gets hit.
Note 1: Even though the duplicated array name segment should not exist in this case, care should be taken to ensure that there are no other cases in which it should.
Note 2: DispatchPostEditToNodes() is also called when the user edits a Global Parameter of the State Tree, which is stored in a PropertyBag. In this case, for an array element in older engine versions, the FPropertyChangedChainEvent used to contain a property chain roughly equivalent to path "ArrayName[ArrayIndex].ArrayName_Inner" or "ArrayName[ArrayIndex].ArrayName". However, the duplicated "tail type" is no longer included by the PropertyBag's CreatePropertyFromDesc(). Moreover, for Global Parameter changes, the StateTree's DispatchPostEditToNodes() function does not attempt to generate or match a "TargetPath", since global parameters cannot currently be bound.
Note 3: This issue repros from at least UE 5.5 (probably earlier)
Note 4: The linked EPS case includes a possible fix for the issue.
1. Make sure plugin GameplayStateTree is enabled
2. On the Content Browser, create and edit a new StateTree asset
Repro with State Parameter:
3. On the StateTree editor:
3.1. Select the Root state
3.2. Add Parameter, change its type to Float Array
3.3. Add one or more elements to the array
3.4. Bind an array element (a single float) to "Property Functions – Math – Float – Add"
3.5. Edit the value of either the "left" or "right" parameters
3.6. An ensure() is hit in UE::StateTree::PropertyHelpers::DispatchPostEditToNodes()
Repro with StateTreeTask parameters:
4. From the StateTree editor, create a new Task
5. On the StateTreeTask editor:
5.1. Create a new instance-editable variable of type Float Array
5.2. Compile, save, close
6. Back on the StateTree editor:
6.1. Add a Task (either Global or in the Root State), select the newly created task from above
6.2. Add one or more elements to the float array
6.3. Bind an array element (a single float) to "Property Functions – Math – Float – Add"
6.4. Edit the value of either the "left" or "right" parameters
6.5. An ensure() is hit in UE::StateTree::PropertyHelpers::DispatchPostEditToNodes()
Note: The linked EPS case also contains a repro project. Steps:
1. Open ST_Example
2. On the "Run EQS Node", expand the "Run EQS Query" Task
3. Locate the Query Config Index[0] value which is bound to an addition Property Function
4. Edit either the left or right value
5. An ensure() is hit in UE::StateTree::PropertyHelpers::DispatchPostEditToNodes()
UE::StateTree::PropertyHelpers::DispatchPostEditToNodes(UObject & Owner, FPropertyChangedChainEvent & InPropertyChangedEvent, UStateTreeEditorData & EditorData) Line 162
UStateTreeState::PostEditChangeChainProperty(FPropertyChangedChainEvent & PropertyChangedEvent) Line 341
FPropertyNode::NotifyPostChange::__l14::<lambda_1>::operator()(UObject *) Line 3419
FPropertyNode::NotifyPostChange(FPropertyChangedEvent & InPropertyChangedEvent, FNotifyHook * InNotifyHook) Line 3423
FPropertyValueImpl::ImportText(const TArray<FObjectBaseAddress,TSizedDefaultAllocator<32>> & InObjects, const TArray<FString,TSizedDefaultAllocator<32>> & InValues, FPropertyNode * InPropertyNode, unsigned int Flags) Line 676
FPropertyValueImpl::ImportText(const FString & InValue, FPropertyNode * InPropertyNode, unsigned int Flags) Line 314
FPropertyValueImpl::ImportText(const FString & InValue, unsigned int Flags) Line 179
FPropertyHandleFloat::SetValue(const float & NewValue, unsigned int Flags) Line 4228
SPropertyEditorNumeric<float>::OnValueCommitted(float NewValue, ETextCommit::Type CommitInfo) Line 531
TDelegate<void __cdecl(float,enum ETextCommit::Type),FDefaultDelegateUserPolicy>::ExecuteIfBound(float) Line 644
SSpinBox<float>::CommitValue(float NewValue, double NewSpinValue, SSpinBox<float>::ECommitMethod CommitMethod, ETextCommit::Type OriginalCommitInfo, const bool bShouldCommit) Line 1055
SSpinBox<float>::TextField_OnTextCommitted(const FText & NewText, ETextCommit::Type CommitInfo) Line 987
TDelegate<void __cdecl(FText const &,enum ETextCommit::Type),FDefaultDelegateUserPolicy>::ExecuteIfBound(const FText &) Line 644
SEditableText::OnTextCommitted(const FText & InText, const ETextCommit::Type InTextAction) Line 737
FSlateEditableTextLayout::HandleCarriageReturn(bool isRepeat, int UserIndex) Line 1664
FSlateEditableTextLayout::HandleKeyDown(const FKeyEvent & InKeyEvent) Line 1096
SEditableText::OnKeyDown(const FGeometry & MyGeometry, const FKeyEvent & InKeyEvent) Line 286
FSlateApplication::ProcessKeyDownEvent::__l22::<lambda_2>::operator()(const FArrangedWidget &) Line 4992
FEventRouter::Route<FReply,FEventRouter::FBubblePolicy,FKeyEvent,`FSlateApplication::ProcessKeyDownEvent'::`22'::<lambda_2>>(FSlateApplication * ThisApplication, FEventRouter::FBubblePolicy RoutingPolicy, FKeyEvent EventCopy, const FSlateApplication::ProcessKeyDownEvent::__l22::<lambda_2> & Lambda, ESlateDebuggingInputEvent DebuggingInputEvent) Line 470
FEventRouter::RouteAlongFocusPath(FSlateApplication *) Line 439
FSlateApplication::ProcessKeyDownEvent(const FKeyEvent & InKeyEvent) Line 4988
FSlateApplication::OnKeyDown(const int KeyCode, const unsigned int CharacterCode, const bool IsRepeat) Line 4899
FWindowsApplication::ProcessDeferredMessage(const FDeferredWindowsMessage & DeferredMessage) Line 3367
FWindowsApplication::DeferMessage(TSharedPtr<FWindowsWindow,1> & NativeWindow, HWND__ * InHWnd, unsigned int InMessage, unsigned __int64 InWParam, __int64 InLParam, int MouseX, int MouseY, unsigned int RawInputFlags) Line 4233
FWindowsApplication::ProcessMessage(HWND__ * hwnd, unsigned int msg, unsigned __int64 wParam, __int64 lParam) Line 2453
WindowsApplication_WndProc(HWND__ *) Line 2240
FWindowsApplication::AppWndProc(HWND__ * hwnd, unsigned int msg, unsigned __int64 wParam, __int64 lParam) Line 2246
WinPumpMessages() Line 212
FWindowsPlatformApplicationMisc::PumpMessages(bool bFromMainLoop) Line 241
FEngineLoop::Tick() Line 5769
EngineTick() Line 60
GuardedMain(const wchar_t * CmdLine) Line 190
LaunchWindowsStartup(HINSTANCE__ * hInInstance, HINSTANCE__ * hPrevInstance, char * __formal, int nCmdShow, const wchar_t * CmdLine) Line 266
WinMain(HINSTANCE__ * hInInstance, HINSTANCE__ * hPrevInstance, char * pCmdLine, int nCmdShow) Line 336
There's no existing public thread on this issue, so head over to Questions & Answers just mention UE-368643 in the post.
| 0 |
| Component | UE - AI - StateTree |
|---|---|
| Affects Versions | 5.7, 5.8 |
| Created | Mar 5, 2026 |
|---|---|
| Updated | May 1, 2026 |