UObject pointer is none on opening editor

I am trying to create a class for like an ECCInt (error checking and clamping integer) and supposedly UObject is less likely to get GC’d and UObject is the lightest for things that have UCLASS, and I was also thinking of using a similar thing for my InventoryItem (so I don’t have like 20-50 Actors/ActorComponents running around on any/every character that has an inventory adding to Cast or Cast overhead when an inventorySlotItem for each slot that can have its stuff overriden as needed would diminish most of that Cast overhead)
while working though Live Coding I found that everything would functionally work as expected (save for a few fixable logical error I was able to fix), I closed the Editor and when I re-opened it later trying to test something else the Editor crashed with an “attempting to access [CustomUObject] accessed none” after going through this

I found the only way to get a new instance of the CustomUObject was to re-add the ActorComponent that had it (needing to redo the get(reference) node links), and again it worked until I closed the editor, and re-opened it. instead of hitting Play to test it. I checked the component in the Blueprint where it was supposed to be stored, and it was “none”

even breaking this part of the project out into its own test project: bringing it down to the 3rd person template(blueprint) and 2 classes with no other dependencies still produces the same behavior.

when trying to recreate this situation in pure blueprints:
-created a BP_ClampInt:UObject that is roughly similar to my ClampInt(h/cpp)
-created a BP_ActorComp:ActorComp that holds a BP_ClampInt reference set from the BP_ActorComp opened from the ContentBrowser, and can call its functions
-created a BP_CharacterBase:Pawn that has a BP_ActorComp in the Components hierarchy to call the functions of BP_ActorComp

this has the same behavior when I exit the editor it doesn’t retain the reference/pointer to the UObject the variables that should hold the references are still in the blueprint, but specifically the BP_ClampInt is none (at least for the pure blueprints I can drag a new instance of the BP_ClampInt from the ContentBrowser and directly assign it)

A few specific questions/thoughts I had about this:
-I can’t figure out how to set the instance of the CustomUObject to be a default of the CustomActorComponent
-when exiting the Play session, and in the same editor session the component is retaining its values from the Play session instead of returning to what should be the defaults of the instance if not the class, as the values set outside of Play session are supposed to be used in the Play session meaning returning to instance defaults after Play session would be important for consistent testing.

the example in c++ I have:
new Games project: ThirdPerson, Blueprint, Start_Content = false, name = “RefCrashTest”

create “ClampInt”:UObject

create “ActorComp”:ActorComponent

ClampInt.h

// Fill out your copyright notice in the Description page of Project Settings.
#pragma once

#include "CoreMinimal.h"
#include "UObject/NoExportTypes.h"
#include "ClampInt.generated.h"

/**
 * Error Checking and Clamping Int
 * favors max (could add control value/enum for favor: max, min, floating)
 */
UCLASS()
class REFCRASHTEST_API UClampInt : public UObject {
	GENERATED_BODY()

public:
	UPROPERTY(VisibleAnywhere, Category=Clamped)
	int Current;
	UPROPERTY(EditAnywhere, Category=Clamped)
	int Min;
	UPROPERTY(EditAnywhere, Category=Clamped)
	int Max=100;
	UPROPERTY(VisibleAnywhere, Category=Clamped)
	int Missing;
	
	void OnInit();
	void OnReset();
	void IncreaseCurrent(int inRHS);
	void DecreaseCurrent(int inRHS);
	void IncreaseMin(int inRHS);
	void DecreaseMin(int inRHS);
	void IncreaseMax(int inRHS);
	void DecreaseMax(int inRHS);

	void OnCheck();
	
	void WreckIt();
};

ClampInt.cpp

// Fill out your copyright notice in the Description page of Project Settings.
#include "ClampInt.h"

void UClampInt::OnInit() {
	if (Min < Max) {
		Current = Max;
		Missing = 0;
	}
}

void UClampInt::OnReset() {
	if (Min < Max) {
		Current = Min;
		Missing = (Max-Min);
	}
}

void UClampInt::IncreaseCurrent(int inRHS) {
	if (inRHS < 0) {
		inRHS *= (-1);
		DecreaseCurrent(inRHS);
	}
	else {
		OnCheck();
		if (Max != Min) {
			if (inRHS < Missing) {
				Current += inRHS;
				Missing -= inRHS;
			}
			else {
				Current = Max;
				Missing = 0;
			}
		}
	}
}

void UClampInt::DecreaseCurrent(int inRHS) {
	if (inRHS < 0) {
		inRHS *= (-1);
		IncreaseCurrent(inRHS);
	}
	else {
		OnCheck();
		if (Max != Min) {
			if (inRHS < Current) {
				Current -= inRHS;
				Missing += inRHS;
			}
			else {
				Current = Min;
				Missing = Max;
			}
		}
	}
}

void UClampInt::IncreaseMin(int inRHS) {
	if (inRHS < 0) {
		inRHS *= (-1);
		DecreaseMin(inRHS);
	}
	else {
		OnCheck();
		if (Max != Min) {
			Min += inRHS;
			if (Min >= Max) {
				Current = Max = Min;
				Missing = 0;
			}
			else {
				Current += inRHS;
				if (Current > Max) {
					Current = Max;
				}
				Missing = Max - Current;
			}
		}
	}
}

void UClampInt::DecreaseMin(int inRHS) {
	if (inRHS < 0) {
		inRHS *= (-1);
		IncreaseMin(inRHS);
	}
	else {
		OnCheck();
		if (Max != Min) {
			Min -= inRHS;
		}
	}
}

void UClampInt::IncreaseMax(int inRHS) {
	if (inRHS < 0) {
		inRHS *= (-1);
		DecreaseMax(inRHS);
	}
	else {
		OnCheck();
		if (Max != Min) {
			Max += inRHS;
			Current += inRHS;
		}
	}
}

void UClampInt::DecreaseMax(int inRHS) {
	if (inRHS < 0) {
		inRHS *= (-1);
		IncreaseMax(inRHS);
	}
	else {
		OnCheck();
		if (Max != Min) {
			Max -= inRHS;
			if (Max > Min) {
				if (Current > Max) {
					Current = Max;
					Missing = 0;
				}
				else {
					Missing = Max - Current;
				}
			}
			else if (Max == Min) {
				Current = Min;
				Missing = 0;
			}
			else {
				Max = Current = Min;
				Missing = 0;
			}
		}
	}
}

void UClampInt::OnCheck() {
	if (!(Current > Min) && !(Current < Max)) {
		OnReset();
	}
	if ((Current + Missing) != Max) {
		OnReset();
	}
}

void UClampInt::WreckIt(){
	Current = Max * 2;
}

ActorComp.h

// Fill out your copyright notice in the Description page of Project Settings.
#pragma once

#include "CoreMinimal.h"
#include "Components/ActorComponent.h"
#include "ClampInt.h"
#include "ActorComp.generated.h"


UCLASS(ClassGroup = (Custom), meta = (BlueprintSpawnableComponent))
class REFCRASHTEST_API UActorComp : public UActorComponent {
	GENERATED_BODY()

public:
	UPROPERTY(Instanced, EditAnywhere, Category = GameTest)
	TObjectPtr<UClampInt> ClampedInt;
	// Sets default values for this component's properties
	UActorComp();

protected:
	// Called when the game starts
	virtual void BeginPlay() override;

public:
	UFUNCTION(BlueprintCallable)
	void IncreaseMax(int inVal);
	UFUNCTION(BlueprintCallable)
	void DecreaseMax(int inVal);
	UFUNCTION(BlueprintCallable)
	void IncreaseMin(int inVal);
	UFUNCTION(BlueprintCallable)
	void DecreaseMin(int inVal);
	UFUNCTION(BlueprintCallable)
	void IncreaseCurrent(int inVal);
	UFUNCTION(BlueprintCallable)
	void DecreaseCurrent(int inVal);
	UFUNCTION(BlueprintCallable)
	void WreckIt();
	

	void ResetObject();

	// Called every frame
	virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;
};

ActorComp.cpp

// Fill out your copyright notice in the Description page of Project Settings.
#include "ActorComp.h"

// Sets default values for this component's properties
UActorComp::UActorComp() {
	// Set this component to be initialized when the game starts, and to be ticked every frame.  You can turn these features
	// off to improve performance if you don't need them.
	PrimaryComponentTick.bCanEverTick = true;
	ClampedInt = NewObject<UClampInt>();
	// ...
}

// Called when the game starts
void UActorComp::BeginPlay() {
	Super::BeginPlay();
	ClampedInt->OnInit();
}

void UActorComp::IncreaseMax(int inVal) { ClampedInt->IncreaseMax(inVal); }
void UActorComp::DecreaseMax(int inVal) { ClampedInt->DecreaseMax(inVal); }
void UActorComp::IncreaseMin(int inVal) { ClampedInt->IncreaseMin(inVal); }
void UActorComp::DecreaseMin(int inVal) { ClampedInt->DecreaseMin(inVal); }
void UActorComp::IncreaseCurrent(int inVal) { ClampedInt->IncreaseCurrent(inVal); }
void UActorComp::DecreaseCurrent(int inVal) { ClampedInt->DecreaseCurrent(inVal); }
void UActorComp::WreckIt() { ClampedInt->WreckIt(); }

void UActorComp::ResetObject() { ClampedInt->OnReset(); }

// Called every frame
void UActorComp::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) {
	Super::TickComponent(DeltaTime, TickType, ThisTickFunction);

	// ...
}

Build in VS to Luanch Editor
Create an InputAction “IA_Debug” with Digital Bool
in IMC_Default assign “IA_Debug” to “Num0” (or the key of your choice)
in BP_ThirdPersonCharacter
in Blueprint editor: “+Add”->ActorComp to Components hierarchy
when selected Details “Game Test” {should be under Sockets} which should have a “Clamped Int” with an expandable of “ClampInt” and another expandable for the 4 ints
making sure Max is 100

create IA_Debug event
drag the “ActorComp” component into the graph
extend out the output pin (as long as “context sensitive” is true most of the nodes will come from this) to get

Save and Compile the Blueprint
Run Game, and trigger the IA_Debug event
you can find the values during Play in the Outliner-> BP_ThirdPersonCharacter0 in details select ActorComp in details section at the top is “Game Test”
final values should be 10, 10, 100, 0
the last values in the Play session are also now the values in the Blueprint
Save all and Exit
Exit Editor

re-open editor through VS
re-open BP_ThirdPersonCharacter (if you didn’t close it then there should be a notification asking if you want to re-open it anyways)

the ActorComp:actorComponent now has its ClampedInt set to None the only way I have found to get it back is to create a new instance of the ActorComp in the Hierarchy which requires re-attaching all the nodes
sometimes re-building in Editor after running this blueprint script may cause the Editor to crash…

*what am I missing to make sure that the instance of ClampedInt doesn’t get set to none when exiting/opening the editor
*BlueprintType on UClampInt doesn’t seem to make a difference, and even when I try to reproduce this in pure blueprints I get similar behavior.

I was able to fix not being able to save the numeric modifications with
ClampInt.h (12) from

UCLASS(BlueprintType)

to

UCLASS(BlueprintType, DefaultToInstanced)

and fixing the "reference to ‘none’/‘null’/‘nullptr’ "
ActorComp.h (10) form

UCLASS(ClassGroup = (Custom), meta = (BlueprintSpawnableComponent))

to

UCLASS(DefaultToInstanced, ClassGroup = (Custom), meta = (BlueprintSpawnableComponent))

though this does create a different bug that would probably be outside the scope of this question.