How to properly setup Actor's SceneComponents?

I have an Actor class (AWorldItem) that loads its StaticMesh dynamically. Rather than create large PostProcess volumes, I decided to go with smaller movable PostProcessComponents attached to the Items. Each item is wrapped (using CalcBounds) by a translucent StaticMesh volume with a PostProcess material that defines the bounds for a PostProcessComponent. I got it working fairly well, but I’ve noticed errors in the logs regarding RegisterComponent:

[2020.06.07-15.52.53:237][ 0]LogOutputDevice: Error: [Callstack] 0x00007ffae442c119 UE4Editor-Engine.dll!::operator()() [d:\build++ue4\sync\engine\source\runtime\engine\private\components\actorcomponent.cpp:1153]
[2020.06.07-15.52.53:237][ 0]LogOutputDevice: Error: [Callstack] 0x00007ffae2fce1d1 UE4Editor-Engine.dll!UActorComponent::RegisterComponent() [d:\build++ue4\sync\engine\source\runtime\engine\private\components\actorcomponent.cpp:1153]
[2020.06.07-15.52.53:237][ 0]LogOutputDevice: Error: [Callstack] 0x00007ffad0d3bf0f UE4Editor-MSR-0002.dll!AWorldItem::AWorldItem() [d:\unreal projects\msr\source\msr\private\worlditem.cpp:34]

AWorldItem.h:

    UCLASS(Blueprintable)
    class AWorldItem : public AActor
    {
    	GENERATED_BODY()
    	
    	AWorldItem(const FObjectInitializer& ObjectInitializer = FObjectInitializer::Get());
    
    	// The BaseItem data for this item, including the Mesh
    	UPROPERTY(EditAnywhere, BlueprintReadOnly, meta = (AllowPrivateAccess = "true"))
    		UBaseItem* BaseItem;

            // The instanced data for this Item
        UPROPERTY(EditAnywhere, BlueprintReadOnly, meta = (AllowPrivateAccess = "true"))
	        UItemInstance* ItemInstance;
    
    	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, meta = (AllowPrivateAccess = "true"))
    		UStaticMeshComponent* MeshComponent;
    
    	// This volume surrounds the Item with a PostProcess Material
    	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, meta = (AllowPrivateAccess = "true"))
    		UStaticMeshComponent* OutlineVolume;
    
    	// Allows for localized Post Process effects
    	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, meta = (AllowPrivateAccess = "true"))
    		UPostProcessComponent* PostProcessor;
    
    	// The Item Outline Effect to use when looking at this Item
    	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, meta = (AllowPrivateAccess = "true"))
    		UMaterialInstance* OutlineMaterialInstance;
    
    	//AActor Interface
    	virtual void BeginPlay() override;
    	
    	// Load the mesh from BaseItem DataAsset into memory, if invalid
    	UFUNCTION()
    		void LoadMesh();
    
    	// Called once the Static Mesh asset is loaded
    	UFUNCTION()
    		void MeshLoaded();
    };

AWorldItem.cpp:

    // Sets up the components, but most features are done on BeginPlay()
    AWorldItem::AWorldItem(const FObjectInitializer& ObjectInitializer)
    	: Super(ObjectInitializer)
    {
     	// Most item actions are called through Events and do not need to Tick
    	PrimaryActorTick.bCanEverTick = false;
    
    	// World-visible Items need replication
    	bReplicates = true;
    	
    	// Create the Component, but don't load the Mesh just yet
    	MeshComponent = CreateDefaultSubobject<UStaticMeshComponent>("WorldItemMesh");
    	MeshComponent->SetupAttachment(RootComponent, "ItemSocket");
    	RootComponent = MeshComponent;
    
    	// Attach the Outline Volume, but don't initialize it until Mesh is loaded
    	OutlineVolume = CreateDefaultSubobject<UStaticMeshComponent>("OutlineVolume");
    	OutlineVolume->SetupAttachment(MeshComponent);
    	OutlineVolume->RegisterComponent();  // Required to modify components later
    
    	// Post Process bounds are defined by the OutlineVolume above
    	PostProcessor = CreateDefaultSubobject<UPostProcessComponent>("OutlinePostProcess");
    	PostProcessor->bUseAttachParentBound = true;
    	PostProcessor->SetupAttachment(OutlineVolume);
    	PostProcessor->RegisterComponent();  // Required to modify components later
    
    }
    
    
    void AWorldItem::BeginPlay()
    {
    	Super::BeginPlay();
    
    	// BaseItem cannot be null.  If it's null, delete the item.
    	if (BaseItem == nullptr)
    	{
    		GetWorld()->DestroyActor(this, true);
    		}
    		return;
    	}
    	
    	// OutlineVolume is set in the Editor and should be valid
    	if (OutlineVolume == nullptr || OutlineVolume->GetStaticMesh() == nullptr)
    	{
    		return;
    	}
    
    	// No Item Instance here means this item was placed or spawned directly
    	if (!ItemInstance)
    	{
    		// Create new ItemInstance, pair it with this, and check for validity
    		ItemInstance = NewObject<UItemInstance>();
    		if (!ItemInstance || !ItemInstance->PairWorldItem(this))
    		{
    			GetWorld()->DestroyActor(this, true);
    			return;
    		}
                    ItemInstance->Init();
    	}
    	
    	LoadMesh();
    }
    
    // If needed, Async load the BaseItem's mesh asset into memory
    void AWorldItem::LoadMesh()
    {
    	// If Null, Item's Mesh has not been loaded yet.  Perform Async Load.
    	if (BaseItem->GetMesh() == nullptr)
    	{
    		FPrimaryAssetId ItemID = BaseItem->GetPrimaryAssetId();
    		if (ItemID.IsValid())
    		{
    			TArray<FName> ItemMesh = { "ItemMesh" };
    			GEngine->AssetManager->LoadPrimaryAsset(ItemID, ItemMesh, FStreamableDelegate::CreateUObject(this, &AWorldItem::MeshLoaded));
    		}
    		return;
    	}
    	else
    	{
    		MeshLoaded();
    	}
    }
    
    // Called after we're sure the Item's Mesh is ready for use
    void AWorldItem::MeshLoaded()
    {
    	// Mesh SHOULD be valid at this point
    	if (BaseItem->GetMesh() == nullptr)
    	{
    		return;
    	}
    
    	MeshComponent->SetStaticMesh(BaseItem->GetMesh());
    	
    	// Enable stencil for the Mesh's outline
    	MeshComponent->SetRenderCustomDepth(true);
    	MeshComponent->SetCustomDepthStencilValue(1);  // TODO: Update based on Item Instance features
    
    	// Needed for the Editor (won't render Mesh otherwise)
    	MeshComponent->RegisterComponent();

        // NOTE: PIE crashes here if I change any of the Attach or RegisterComponent lines.
    	// Now that the Mesh is loaded, update the Outline Volume transform
    	FBoxSphereBounds MeshBounds = MeshComponent->CalcBounds(FTransform());
    	FBoxSphereBounds OutlineBounds = OutlineVolume->CalcBounds(FTransform());
    
    	// Center Outline Volume on the Mesh
    	OutlineVolume->SetRelativeLocation(FVector(MeshBounds.Origin.X, MeshBounds.Origin.Y, MeshBounds.Origin.Z));
    
    	// Outline Volume needs to be larger than the Mesh (thus x1.0625)
    	// All Divisors also need to be non-zero (thus add 1 to each)
    	OutlineVolume->SetRelativeScale3D(FVector(
    		MeshBounds.BoxExtent.X/(OutlineBounds.BoxExtent.X + 1),
    		MeshBounds.BoxExtent.Y/(OutlineBounds.BoxExtent.Y + 1),
    		MeshBounds.BoxExtent.Z/(OutlineBounds.BoxExtent.Z + 1))*1.0625);
    
    	// Should have been set in the Editor
    	if (OutlineMaterialInstance == nullptr)
    	{
    		return;
    	}
    
    	// Why do I need these calls again?  Is it because the Constructor is not being called in PIE?
    	OutlineVolume->RegisterComponent();
    	PostProcessor->RegisterComponent();
    }

It works, but I’m pretty sure I’m setting up the components wrong. What is the proper way to use RegisterComponent and SetupAttachment (or AttachToComponent)?