Remote Control HTTP request for Blueprint Function library for MetaHuman Creation

Hi,
i have a very strange problem. I’m working with the Metahuman API on 5.7 (started on the preview of 5.7) and I’m building a tool that where by pressing only one button you can create your Metahuman without using the MetaHuman creator asset directly, by passing some parameters, and this method is executed by an HTTP request. Here the code of the method.

void UMetaHumanBuilder_API::MakeMetaHumanCharacterCreator(bool& bSuccess,
                                                          const FString InCharacterCreatorName,
                                                          const FString InMetaHumanIdentitySKName,
                                                          const FString InBodyConstraintCSVName)
{
	UE_LOG(LogTemp, Display, TEXT(">>> MakeMetaHumanCharacterCreator. BlueprintFunction library Start <<<"));
	bSuccess = true;

	// Construct Full path
	const FString CharacterCreatorFullPath = "/Game/MetaHumanBuilder/MH_Creation/" + InCharacterCreatorName;
	const FString MetaHumanSKFullPath =  "/Game/MetaHumanBuilder/MH_Identity/" + InMetaHumanIdentitySKName;
	const FString CSVFullPath = FPaths::ProjectDir() + TEXT("CSV_BodyConstraint/") + InBodyConstraintCSVName;

	// Load asset passed by path
	UMetaHumanCharacter* MetaHumanCharacter = LoadAsset<UMetaHumanCharacter>(CharacterCreatorFullPath);
	if (MetaHumanCharacter == nullptr)
	{
		UE_LOG(LogTemp, Error, TEXT("Errore nel caricamenti di %s"), *CharacterCreatorFullPath);
		MetaHumanCharacter = CreateMetaHumanCharacter(CharacterCreatorFullPath);
	}

	USkeletalMesh* TemplateMesh = LoadAsset<USkeletalMesh>(MetaHumanSKFullPath);
	if (TemplateMesh == nullptr)
	{
		UE_LOG(LogTemp, Error, TEXT("Errore nel caricamento della skeletal mesh %s."), *MetaHumanSKFullPath);
		UE_LOG(LogTemp, Error, TEXT("Make sure to create a MetaHumanIdentity first."));
		bSuccess = false;
		return;
	}

	TArray<FMetaHumanCharacterBodyConstraint> BodyConstraints{};
	
	// Load body constraint from CSV
	UDataTable* BodyConstraintDataTable = NewObject<UDataTable>();
	BodyConstraintDataTable->RowStruct = FBodyConstraintRow::StaticStruct();
	bool bSuccessImport = UDataTableFunctionLibrary::FillDataTableFromCSVFile(BodyConstraintDataTable, CSVFullPath);

	if (!bSuccessImport)
	{
		UE_LOG(LogTemp, Error, TEXT("Impossibile riempire la DataTable dal file CSV: %s"), *CSVFullPath);
		bSuccess = false;
		return;
	}

	// Apply body constraint on metahuman
	TArray<FName> RowsName = BodyConstraintDataTable->GetRowNames();
	FString Context = "BodyConstraintInfo";
	for (int i=0; i < RowsName.Num(); i++)
	{
		// Retrieve row by name
		FBodyConstraintRow* BodyConstraintRow =
			BodyConstraintDataTable->FindRow<FBodyConstraintRow>(RowsName[i], Context);


		if (BodyConstraintRow)
		{
			bool bIsConstraintActive = BodyConstraintRow->IsActive.Equals(TEXT("True"), ESearchCase::IgnoreCase);
			
			FMetaHumanCharacterBodyConstraint NewBodyConstraint{
				FName(BodyConstraintRow->Name),
				bIsConstraintActive,
				BodyConstraintRow->Target,
				BodyConstraintRow->Min,
				BodyConstraintRow->Max};
		
			BodyConstraints.Add(NewBodyConstraint);
		}
		
	}

	UMetaHumanCharacterEditorSubsystem* MetaHumanCharacterEditorSubsystem = UMetaHumanCharacterEditorSubsystem::Get();

	if (!IsValid(MetaHumanCharacterEditorSubsystem))
	{
		UE_LOG(LogTemp, Error, TEXT("Impossibile ottenere UMetaHumanCharacterEditorSubsystem!"));
		bSuccess = false;
		return;
	}
	
	if (!MetaHumanCharacter->IsCharacterValid())
	{
		MetaHumanCharacterEditorSubsystem->InitializeMetaHumanCharacter(MetaHumanCharacter);
	}

	if (!MetaHumanCharacterEditorSubsystem->IsObjectAddedForEditing(MetaHumanCharacter))
	{
		if (!MetaHumanCharacterEditorSubsystem->TryAddObjectToEdit(MetaHumanCharacter))
		{
			UE_LOG(LogTemp, Error, TEXT("--- Try AddObjectTo Edit failed."));
			bSuccess = false;
			return;
		}
		else
		{
			UE_LOG(LogTemp, Error, TEXT("--- Try AddObjectTo Edit success."));
		}
	}
	
	MetaHumanCharacterEditorSubsystem->SetBodyConstraints(MetaHumanCharacter, BodyConstraints);
	MetaHumanCharacterEditorSubsystem->CommitBodyState(MetaHumanCharacter);
	
	EImportErrorCode errorCode =  MetaHumanCharacterEditorSubsystem->ImportFromTemplate(MetaHumanCharacter, TemplateMesh,
		nullptr, nullptr, nullptr,
		FImportFromTemplateParams{
		false,
		true,
		true,
		EAlignmentOptions::ScalingRotationTranslation});

	

	UE_LOG(LogTemp, Display, TEXT("%d"), errorCode);
	
	
	if (MetaHumanCharacter->NeedsToDownloadTextureSources())
	{
		FMetaHumanCharacterTextureRequestParams RequestParams;
		RequestParams.bBlocking = true;
		RequestParams.bReportProgress = false;

		UE_LOG(LogTemp, Display, TEXT("Avvio del download delle texture per '%s'... (Questa operazione potrebbe richiedere tempo)"), *MetaHumanCharacter->GetName());
    
		MetaHumanCharacterEditorSubsystem->RequestTextureSources(MetaHumanCharacter, RequestParams);
	}
	
	MetaHumanCharacterEditorSubsystem->RequestAutoRigging(MetaHumanCharacter, FMetaHumanCharacterAutoRiggingRequestParams{
	EMetaHumanRigType::JointsOnly,
	false,
	true});
	
	/*
	if (MetaHumanCharacterEditorSubsystem->CanBuildMetaHuman(MetaHumanCharacter, true))
	{
		MetaHumanCharacterEditorSubsystem->BuildMetaHuman(MetaHumanCharacter,
			FMetaHumanCharacterEditorBuildParameters{
			EMetaHumanDefaultPipelineType::Optimized,
			EMetaHumanQualityLevel::Cinematic,
			EName::None,
			"",
			"",
			"",
			true,
			false,
			true});
	}
	*/

	if (MetaHumanCharacterEditorSubsystem->IsObjectAddedForEditing(MetaHumanCharacter))
	{
		MetaHumanCharacterEditorSubsystem->RemoveObjectToEdit(MetaHumanCharacter);	
	}

	SaveAsset(MetaHumanCharacter);
		
	bSuccess = true;
	UE_LOG(LogTemp, Display, TEXT(">>> MakeMetaHumanCharacterCreator. BlueprintFunction library END <<<")); 
}

As i said, i’m using this method to create a MetaHuman Character Creator Asset, and create a MetaHuman with it, without using the UI.

Now the problem is that if i call this method from an Editor Utility Widget the method works fine, and it is executed until the end and give the right result, a metaHuman character creator asset, and also a builded metahuman i a decomment the code.
If i try to call this method by using an HTTP request i receive some errors and the editor crash
This is the crash report. The row 1173 is the one where there is the method RequestAutoRigging.

LoginId:bb901f7c40b11691f1e68f9c0f173e49
EpicAccountId:7aa50a71778e4fa2a9dc13a5bc25d276

Assertion failed: IsValid() [File:D:\build\++UE5\Sync\Engine\Source\Runtime\Core\Public\Templates\SharedPointer.h] [Line: 1112] 



UnrealEditor_Core
UnrealEditor_Core
UnrealEditor_MetaHumanCharacterEditor
UnrealEditor_MetaHumanCharacterEditor
UnrealEditor_MetaHumanBuilder!UMetaHumanBuilder_API::MakeMetaHumanCharacterCreator() [C:\Users\Tony\Documents\Unreal Projects\MetaHumanBuilder\Source\MetaHumanBuilder\Private\MetaHumanBuilder_API.cpp:1173]
UnrealEditor_MetaHumanBuilder!UMetaHumanBuilder_API::execMakeMetaHumanCharacterCreator() [C:\Users\Tony\Documents\Unreal Projects\MetaHumanBuilder\Intermediate\Build\Win64\UnrealEditor\Inc\MetaHumanBuilder\UHT\MetaHumanBuilder_API.gen.cpp:638]
UnrealEditor_CoreUObject
UnrealEditor_CoreUObject
UnrealEditor_RemoteControl
UnrealEditor_WebRemoteControl
UnrealEditor_WebRemoteControl
UnrealEditor_HTTPServer
UnrealEditor_HTTPServer
UnrealEditor_HTTPServer
UnrealEditor_HTTPServer
UnrealEditor_HTTPServer
UnrealEditor_HTTPServer
UnrealEditor_HTTPServer
UnrealEditor_HTTPServer
UnrealEditor_Core
UnrealEditor_Core
UnrealEditor_Core
UnrealEditor
UnrealEditor
UnrealEditor
UnrealEditor
UnrealEditor
UnrealEditor
kernel32
ntdll

Before the crash in the Log i have these lines

Warning      LogOutputDevice           Script Stack (1 frames) :
Warning      LogOutputDevice           /Script/MetaHumanBuilder.MetaHumanBuilder_API.MakeMetaHumanCharacterCreator
Error        LogWindows                appError called: Assertion failed: IsValid() [File:D:\build\++UE5\Sync\Engine\Source\Runtime\Core\Public\Templates\SharedPointer.h] [Line: 1112] 

I think that the problem is related to requestes like RequestAutoRigging, RequestTextureSources because if i remove them everything is working.
The other strange thing is that in the Unreal engine 5.7 Preview the HTTP the method executed from an HTTP remote control request was working, but now in the official release it’s not working anymore.

If you need it i can also paste the HTML code if it is necessary, or anything that might be helpful.

Some of you have any ideas?

I haven’t worked with MH API, but for async HTTP request, if the result shared pointer is destroyed before the async request finish, it will crash. It needs a valid result object to pass the response data to. I’m just assuming.

you’re probably calling all this stuff before the Metahuman subsystem is initialized. Sometimes things can get initialized in different orders depending on how you launch stuff. Like, Play-In-Editor can be completely different than standalone in terms of when things are called.

So basically are you saying that this might the reason why it’s working if a call the method from editor utility widget and not working if i call it by HTTP request?
Did I understand correctly?
But it is strange because other method before RequestAutoRigging are using the MH Subsystem, but the error is on the method Request auto rigging.
Thanks, I will look in to it.