Package metadata FSoftObjectPaths not updated when using Update Redirector References

I’m not sure how metadata gets added to a package, but if you start with an asset A whose package contains metadata (UPackage::MetaData) that is keyed off an asset B and then:

  1. Move B to location C, leaving behind a redirector
  2. Run the Update Redirector References action in the editor
  3. Delete the redirector
  4. Save all
  5. Validate A

You will get validation errors because A’s MetaData is not updated inside FAssetRenameManager::RenameReferencingSoftObjectPaths. I believe I have a patch that fixes this by adding the following code inside the loop over packages in that function.

		FMetaData& packageMetadata = Package->GetMetaData();
		TMap<FSoftObjectPath, TMap<FName, FString>> newMap;
		for (TMap<FSoftObjectPath, TMap<FName, FString>>::TIterator It(packageMetadata.ObjectMetaDataMap); It; ++It)
		{
			FSoftObjectPath redirectedPath = GRedirectCollector.GetAssetPathRedirection(It.Key());
			if (redirectedPath.IsValid())
			{
				newMap.FindOrAdd(redirectedPath).Append(It.Value());
			}
			else
			{
				// Check whether the base package has been redirected but the object is missing.
				FString oldPackagePath = It.Key().GetLongPackageName();
				// Construct the main object path by reusing the package name as the object name
				FString reconstructedObjectPath = oldPackagePath + TEXT(".") + FPackageName::GetShortName(oldPackagePath);
				FSoftObjectPath redirectedMainObjectPath = GRedirectCollector.GetAssetPathRedirection(reconstructedObjectPath);
				if (redirectedMainObjectPath.IsValid())
				{
					FSoftObjectPath redirectedActualPath = redirectedMainObjectPath.GetLongPackageName() + TEXT(".") + It.Key().GetAssetName();
					if (redirectedActualPath.ResolveObject() != nullptr)
					{
						redirectedActualPath.SetSubPathString(It.Key().GetSubPathString());
						newMap.FindOrAdd(redirectedActualPath).Append(It.Value());
					}
					else
					{
						UE_LOG(LogAssetTools, Error,
							TEXT("The package metadata in %s references a redirected asset %s whose package exist but object does not."),
							*Package->GetPathName(), *It.Key().GetAssetPathString());
						// Object doesn't exist in redirected package
					}
				}
				else
				{
					// No redirector case
					newMap.FindOrAdd(It.Key()).Append(It.Value());
				}
			}
		}
		Package->GetMetaData().ObjectMetaDataMap = newMap;

Does this seem correct? I’m wondering also if it should ever even be possible to have package metadata referring to another package? It seems like the purpose is to embed metadata for subobjects on the package, so I’m guessing that the way you get into this bad state is by copying an object on disk or by branching in p4 rather than going through the proper editor copy operations. Does that sound right?

[Attachment Removed]

Actually, I don’t think this is the right fix. The right fix is probably to create a commandlet that loads every package on disk, looks at its metadata, and fixes up any metadata entries whose keys have a package name that isn’t the same as the package on disk. In other words, the fix isn’t to follow the redirector it’s to get the FSoftObjectPath to point back at itself.

[Attachment Removed]

Hey, thank you for raising this. Were you able to make any headway with the commandlet approach?

I have not found any existing tickets for this, so it’s likely not something we’ve run into before.

To help triage this, were you able to confirm how the packages ended up in this state?

[Attachment Removed]

Hello!

I was able to find a way to reproduce the problem by renaming BPs in successions. I couldn’t find a proper way to prevent or resolve already affected assets. The main problem we are facing is that the Soft References are subjected to the Core Redirects (not the redirectors) on save\load. There is currently no way to prevent the remapping.

I opened an internal bug for the engine team to review. It should soon be visible here: https://issues.unrealengine.com/issue/UE\-401315

Regards,

Martin

[Attachment Removed]