SButton OnMouseEnter generates is not an EInvalidateWidgetReason supported by SlateAttribute

I have a SButton and when the framework calls SButton::OnMouseEnter the code breaks in

void FSlateAttributeMetaData::InvalidateWidget(SWidget& OwningWidget, const FSlateAttributeBase& Attribute, ESlateAttributeType AttributeType, EInvalidateWidgetReason Reason)
{
....

#if WITH_SLATE_DEBUGGING
	ensureAlwaysMsgf(FSlateAttributeBase::IsInvalidateWidgetReasonSupported(Reason), TEXT("%s is not an EInvalidateWidgetReason supported by SlateAttribute."), *LexToString(Reason));
#endif

	OwningWidget.Invalidate(Reason);
}

The given output is for the Reason=223

Ensure condition failed: FSlateAttributeBase::IsInvalidateWidgetReasonSupported(Reason) [File:D:\GitHub\UnrealEngine\Engine\Source\Runtime\SlateCore\Private\Types\SlateAttributeMetaData.cpp] [Line: 365] 
Layout|Paint|Volatility|ChildOrder|RenderTransform|AttributeRegistration|Prepass is not an EInvalidateWidgetReason supported by SlateAttribute.
[2022.05.31-14.28.12:706][683]LogOutputDevice: Error: Ensure condition failed: FSlateAttributeBase::IsInvalidateWidgetReasonSupported(Reason) [File:D:\GitHub\UnrealEngine\Engine\Source\Runtime\SlateCore\Private\Types\SlateAttributeMetaData.cpp] [Line: 365] 
Layout|Paint|Volatility|ChildOrder|RenderTransform|AttributeRegistration|Prepass is not an EInvalidateWidgetReason supported by SlateAttribute.

[2022.05.31-14.28.12:706][683]LogStats:             FDebug::EnsureFailed -  0.000 s
A breakpoint instruction (__debugbreak() statement or a similar call) was executed in KSGMClient-Win64-DebugGame.exe.

I don’t understand why the value 223=11011111 is invalid, since 11011111 is equivalent to

Layout = 1 << 0,
Paint = 1 << 1,
Volatility = 1 << 2,
ChildOrder = 1 << 3,
RenderTransform = 1 << 4,

AttributeRegistration = 1 << 6,
Prepass = 1 << 7,

It does not crash the game, but when debugging, it is really annoying having the debugger breaks each times I hover a button.

constexpr static bool IsInvalidateWidgetReasonSupported(
        EInvalidateWidgetReason Reason)
{
	return (Reason & (EInvalidateWidgetReason::ChildOrder | EInvalidateWidgetReason::AttributeRegistration)) == EInvalidateWidgetReason::None;
}

As you can see IsInvalidateWidgetReasonSupported(Reason) is false because bit 1 << 3 and/or bit 1 << 6 is on, therefore:

ensureAlwaysMsgf(FSlateAttributeBase::IsInvalidateWidgetReasonSupported(Reason),...)

is firing because the condition is false.

The reason they are not supported as reasons is because:

ChildOrder: The update of SlateAttribute is done in the SlatePrepass. We can’t add or remove children in SlatePrepass.

AttributeRegistration: In FastPath, the SlateAttribute are updated in a loop. The iterator can’t be modified while we are looping.

(See SlateAttribute.h)

Txs for your explanation.

But how can I know when the slate is in SlatePrepass or in FastPath.

I’m adding content to a widget dynamically, not necessarily in Construct only. In my case, when the player’s information changed, or when the match is in count down, or starting, …

And the error is firing on SButton::OnMouseEnter()

[2022.06.05-06.14.47:071][970]LogOutputDevice: Error: [Callstack] 0x00007ff68f1b1a64 KSGMClient.exe!FSlateAttributeMetaData::InvalidateWidget() [D:\GitHub\UnrealEngine\Engine\Source\Runtime\SlateCore\Private\Types\SlateAttributeMetaData.cpp:365]
[2022.06.05-06.14.47:071][970]LogOutputDevice: Error: [Callstack] 0x00007ff68f1c7923 KSGMClient.exe!SlateAttributePrivate::TSlateAttributeBase<SWidget,bool,SlateAttributePrivate::FSlateAttributeNoInvalidationReason,TSlateAttributeComparePredicate<TEqualTo<void> >,0>::Set() [D:\GitHub\UnrealEngine\Engine\Source\Runtime\SlateCore\Public\Types\Attributes\SlateAttributeBase.inl:285]
[2022.06.05-06.14.47:071][970]LogOutputDevice: Error: [Callstack] 0x00007ff68f1b92a7 KSGMClient.exe!SWidget::OnMouseEnter() [D:\GitHub\UnrealEngine\Engine\Source\Runtime\SlateCore\Private\Widgets\SWidget.cpp:510]
[2022.06.05-06.14.47:071][970]LogOutputDevice: Error: [Callstack] 0x00007ff68f4a7149 KSGMClient.exe!SButton::OnMouseEnter() [D:\GitHub\UnrealEngine\Engine\Source\Runtime\Slate\Private\Widgets\Input\SButton.cpp:429]

I’m not interacting with the mouse enter event.

D.

When I override the OnMouseEnter() and the OnMouseLeave() in my class SKButton, the error disappears.

protected:
	/** Begin SWidget interface */
	virtual int32 OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyClippingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled) const override;
	virtual FVector2D ComputeDesiredSize(float LayoutScaleMultiplier) const override;
	virtual void OnMouseEnter(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override;
	virtual void OnMouseLeave(const FPointerEvent& MouseEvent) override;
	/** End SWidget interface */

and don’t call the SButton base member function, no more error.

void SKButton::OnMouseEnter(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent)
{
	// Don't call parent implementation
	// otherwise it generates an error
	/* @todo Check if the error disappears in future version of UE5 */
	//SButton::OnMouseEnter(MyGeometry, MouseEvent);
}

void SKButton::OnMouseLeave(const FPointerEvent& MouseEvent)
{
	// Don't call parent implementation
	// otherwise it generates an error
	/* @todo Check if the error disappears in future version of UE5 */
	//SButton::OnMouseLeave(MouseEvent);
}

Something should be wrong in SButton::OnMouseEnter() or something somewhere else.