Invalid pointer to some UObjects using Instanced Structs

Hello,

Its been a few days that i’m stuck on a “weird” issue.

For context, my inventory system uses a single UObject type: UPGItem.
This class contains data such as Instanced Structs, used as fragments to make modular items.
For each item those fragments are defined in a Data Asset, and feed to the UPGItem on creation (at this point the fragments are holded in the Item).
I’ve been using that with classes and static meshs the past weeks and got no issues.
Example:

But now, i was testing my equipment system (thats uses the same UPGItem class) and ran into an issue: when i get a specific fragment holded in my item, the ptr is “invalid”.
It passes the IsValid check, but after that when I use the ptr i get a exception. When i use IsValidLowLevel, it fails.

I encountered this issue with UMaterialInterface and TSubclassOf<UGameplayEffect>.

Here is the variable where the instanced structs are saved in UPGItem

	UPROPERTY(Replicated) TArray<TInstancedStruct<FPGBaseItemFragment>> Fragments;

Here is the code of the struct holding the UMaterialInterface

USTRUCT(BlueprintType)
struct FPGCoreEquipmentItemFragment : public FPGBaseItemFragment
{
	GENERATED_BODY();

public:
	UPROPERTY(EditAnywhere, BlueprintReadOnly) UMaterialInterface* TempMaterial;
};

How i get it:

const FPGCoreEquipmentItemFragment* FoundCoreEquipmentItemFragment = CurrentEquippedItem->FindFragment<FPGCoreEquipmentItemFragment>();

the inside of FindFragment (in case it matters):

template <std::derived_from<FPGBaseItemFragment> T>
	const T* FindFragment() const
	{
		for (auto Fragment : Fragments)
		{
			if (Fragment.IsValid())
			{
				if (const T* Frag = Fragment.GetPtr<T>())
				{
					return Frag;
				}
			}
		}
		return nullptr;
	}

How i get the material:

	UMaterialInterface* Mat = FoundCoreEquipmentItemFragment->TempMaterial;

And finally, how I use it:

if (IsValid(SkeletalMeshComponent) && Mat->IsValidLowLevel()) // IsValidLowLevel will always fail
{
	SkeletalMeshComponent->SetMaterial(0, Mat);
}

if (IsValid(SkeletalMeshComponent) && IsValid(Mat)) // IsValid would pass but encounter exception
{
	SkeletalMeshComponent->SetMaterial(0, Mat);
}

Here is how it looks like inside the Data Asset:

And for the issue with the Gameplay Effects, in this 2 entry array, the first is always valid and he second not when getting it in c++

I believe I’m having this same issue for a TSubclassOf, any fix for it yet?

using TSoftClassPtr instead seemed to work for me!