Error: FArchive does not support FWeakObjectPtr serialization. Use FArchiveUObject instead

I’m using the nativization tool to package a project, but it fails with this error. I think I have a good idea of what they problem file might be, but I’m wondering how to solve the problem when I find the bad file.

If anyone could provide any insight on what this error means, that would be awesome.

1 Like

@ [anonymous_user_19cdb1f4] Did you ever solve this issue? I am experiencing it in 5.2 now.

Are you using the FArchive << operator for serialization?

I think so why does that matter?

Any help you could give wud be great.

This bit of my code. RegisterProperty(Property, PrefixID, ClassDef, PropertyOffsets, Meta, Out);
FBinaryArchiveFormatter Fmt(Out);
FStructuredArchive Ar(Fmt);
const auto RootSlot = Ar.Open();
Property->SerializeBinProperty(RootSlot, const_cast<void*>(ContainerPtr));
Ar.Close();
bUpdateOK = true; Crashes because i am trying to Serialize a TArray of TObjectPtrs on my Inventory UObject.

It’s a bit hard to figure out the code on such a small sample but is your out of type FArchive? if so try switching it’s struct to FArchiveUObject and see if the error persists.

FBinaryArchiveFormatter can take in both FArchive and FArchiveUObject

Sorry about that. Here is my full code for that function.

void SavePropertyUtilities::StoreContainerProperty(FProperty* Property, const UObject* RootObject, uint32 PrefixID,
	const void* ContainerPtr, bool bIsArrayElement, int Depth, TSharedPtr<FSaveClassDef> ClassDef,
	TArray<uint32>& PropertyOffsets, FSaveClassMetaData& Meta, FMemoryWriter& Out)
{
	bool bUpdateOK;
	
	if (IsPropertyNativelySupported(Property))
	{
		const void* DataPtr = Property->ContainerPtrToValuePtr<void>(ContainerPtr);
		
		if (const auto SProp = CastField<FStructProperty>(Property))
		{
			if (IsBuiltInStructProperty(SProp))
			{
				bUpdateOK =
					TryWriteBuiltinStructPropertyData<FVector>(SProp, PrefixID, DataPtr, bIsArrayElement, Depth, ClassDef, PropertyOffsets, Meta, Out) ||
					TryWriteBuiltinStructPropertyData<FRotator>(SProp, PrefixID, DataPtr, bIsArrayElement, Depth, ClassDef, PropertyOffsets, Meta, Out) ||
					TryWriteBuiltinStructPropertyData<FTransform>(SProp, PrefixID, DataPtr, bIsArrayElement, Depth, ClassDef, PropertyOffsets, Meta, Out) ||
					TryWriteBuiltinStructPropertyData<FGuid>(SProp, PrefixID, DataPtr, bIsArrayElement, Depth, ClassDef, PropertyOffsets, Meta, Out);
			}
			else
			{
				UE_LOG(LogSaveSystem, Verbose, TEXT("%s:"), *GetLogPrefix(Property, Depth));
				bUpdateOK = true;
			}
		}
		else 
		{
			bUpdateOK =
				TryWritePropertyData<FBoolProperty,		bool>(Property, PrefixID, DataPtr, bIsArrayElement, Depth, ClassDef, PropertyOffsets, Meta, Out) ||
				TryWritePropertyData<FByteProperty,		uint8>(Property, PrefixID, DataPtr, bIsArrayElement, Depth, ClassDef, PropertyOffsets, Meta, Out) ||
				TryWritePropertyData<FUInt16Property,	uint16>(Property, PrefixID, DataPtr, bIsArrayElement, Depth, ClassDef, PropertyOffsets, Meta, Out) ||
				TryWritePropertyData<FUInt32Property,	uint32>(Property, PrefixID, DataPtr, bIsArrayElement, Depth, ClassDef, PropertyOffsets, Meta, Out) ||
				TryWritePropertyData<FUInt64Property,	uint64>(Property, PrefixID, DataPtr, bIsArrayElement, Depth, ClassDef, PropertyOffsets, Meta, Out) ||
				TryWritePropertyData<FInt8Property,		int8>(Property, PrefixID, DataPtr, bIsArrayElement, Depth, ClassDef, PropertyOffsets, Meta, Out) ||
				TryWritePropertyData<FInt16Property,	int16>(Property, PrefixID, DataPtr, bIsArrayElement, Depth, ClassDef, PropertyOffsets, Meta, Out) ||
				TryWritePropertyData<FIntProperty,		int>(Property, PrefixID, DataPtr, bIsArrayElement, Depth, ClassDef, PropertyOffsets, Meta, Out) ||
				TryWritePropertyData<FInt64Property,	int64>(Property, PrefixID, DataPtr, bIsArrayElement, Depth, ClassDef, PropertyOffsets, Meta, Out) ||
				TryWritePropertyData<FFloatProperty,	float>(Property, PrefixID, DataPtr, bIsArrayElement, Depth, ClassDef, PropertyOffsets, Meta, Out) ||
				TryWritePropertyData<FDoubleProperty,	double>(Property, PrefixID, DataPtr, bIsArrayElement, Depth, ClassDef, PropertyOffsets, Meta, Out) ||
				TryWritePropertyData<FStrProperty,		FString>(Property, PrefixID, DataPtr, bIsArrayElement, Depth, ClassDef, PropertyOffsets, Meta, Out) ||
				TryWritePropertyData<FNameProperty,		FName>(Property, PrefixID, DataPtr, bIsArrayElement, Depth, ClassDef, PropertyOffsets, Meta, Out) ||
				TryWritePropertyData<FTextProperty,		FText>(Property, PrefixID, DataPtr, bIsArrayElement, Depth, ClassDef, PropertyOffsets, Meta, Out) ||
				TryWriteEnumPropertyData(Property, PrefixID, DataPtr, bIsArrayElement, Depth, ClassDef, PropertyOffsets, Meta, Out) ||
				TryWriteUObjectPropertyData(Property, PrefixID, DataPtr, bIsArrayElement, Depth, ClassDef, PropertyOffsets, Meta, Out);		
		}
	}
	else
	{
		RegisterProperty(Property, PrefixID, ClassDef, PropertyOffsets, Meta, Out);
		FBinaryArchiveFormatter Fmt(Out);
		FStructuredArchive Ar(Fmt);
		const auto RootSlot = Ar.Open();
		Property->SerializeBinProperty(RootSlot, const_cast<void*>(ContainerPtr));
		Ar.Close();
		bUpdateOK = true;
	}
	
	if (!bUpdateOK)
	{
		UE_LOG(LogSaveSystem, Error, TEXT("Unable to update from property %s, unsupported type."), *Property->GetName());
	}
}

I’m guessing you are trying to branch off SPUD

“In addition, from UE 5.2 uses of TObjectPtr<> inside Arrays and Maps is no longer supported.
UE changed the say these are serialized in the core and have broken compatibility
with FMemoryArchive, which SPUD relies on. Raw UObject pointers are still Supported
in arrays and maps, as are single TObjectPtr vars.”

So you can’t rely on FMemoryArchive. You would need to do custom serialization for objects.

1 Like