Game saves data, but fails to load it


once i join it applies the defualt data fine, but once i rejoin it fails to load, i have been stuck on this bug for days and i dont want to give up

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerStorage = game:GetService("ServerStorage")
local RunService = game:GetService("RunService")
local DataStoreService = game:GetService("DataStoreService")
local database = DataStoreService:GetDataStore("gamedata0")
local HttpService = game:GetService("HttpService")

local MarketPlaceService = game:GetService("MarketplaceService")

local sessionData ={}
local itemData = require(ReplicatedStorage:WaitForChild("ItemData"))

local players = game:GetService("Players")
function GiveCash(player, amount)
	if sessionData[player.UserId] then
		local cash = player.leaderstats:FindFirstChild("Cash")
		sessionData[player.UserId].Cash = sessionData[player.UserId].Cash + amount
		sessionData[player.UserId].TotalCash = sessionData[player.UserId].TotalCash + amount
		if cash then
			cash.Value = sessionData[player.UserId].Cash
		end
	end
end
function GroupRankGreater(player:Player, MinimumRank)
	return player:GetRankInGroup(32577708) >= MinimumRank
end
function GroupRank(player:Player, Rank)
	return player:GetRankInGroup(32577708) == Rank
end
function GiveInvItem(player,ItemID)
	print(ItemID)
	print(itemData)
	print(sessionData[player.UserId].Inventory)
	local hasitem = false
	for _, data in ipairs(sessionData[player.UserId].Inventory) do 
		if data == ItemID then
			hasitem = true
		end
	end
	if not hasitem then
		local inlen = #sessionData[player.UserId].Inventory
		sessionData[player.UserId].Inventory[inlen+1] = ItemID
	end
end
function UpdatePlayerTitle(player) 
	if sessionData[player.UserId] then
		local currentTitle = sessionData[player.UserId].CurrentTitle
		local inventory = sessionData[player.UserId].Inventory
		if currentTitle and inventory then
			local titleItem = inventory[currentTitle]

			if titleItem then
				local displayPart = Instance.new("Part")
				displayPart.Size = Vector3.new(2, 0.2, 2) 
				displayPart.Anchored = true
				displayPart.CanCollide = false
				displayPart.Transparency = 1
				displayPart.Parent = player.Character

				
				local displayLabel = Instance.new("TextLabel")
				displayLabel.Text = titleItem.Name 
				displayLabel.Size = UDim2.new(0, 200, 0, 50)
				displayLabel.TextColor3 = titleItem.Col
				displayLabel.BackgroundTransparency = 1
				displayLabel.Parent = displayPart

				displayLabel.Position = UDim2.new(0, -100, 0, 100) 

				-- Cleanup when the player leaves the game
				player.CharacterRemoving:Connect(function()
					displayPart:Destroy()
				end)
			end
		end
	end
end
function onPlayerEntered(newPlayer:Player)
	local stats = Instance.new("IntValue")
	stats.Name = "leaderstats"


	local cash = Instance.new("IntValue")
	cash.Name = "Cash"

	local totalcash = Instance.new("IntValue")
	totalcash.Name = "TotalCash"
	totalcash.Parent = newPlayer

	cash.Parent = stats


	local success = nil
	local playerData = nil
	local attempt = 1

	repeat 
		success, playerData = pcall(function()
			return database:GetAsync(newPlayer.UserId)
		end) 	

		attempt += 1
		if not success then
			warn(playerData)
			task.wait(3)
		end
	until success or attempt == 5

	if success then
		print("connected player to database")
		if not playerData then
			print("Assigning default data")
			playerData = {
				["Cash"] = 10,
				["TotalDisasters"] = 0,
				["SurvivedDisasters"] = 0,
				["TotalMaps"] = 0,
				["TotalDeaths"] = 0,
				["TotalCash"] = 10,
				["TotalJoins"] = 0,
				["JoinDate"] = os.date(),
				["JoinEpoch"] = os.time(),
				["Banned"] = false,
				["BannedReason"] = "No Reason Given",
				["BannedUntil"] = 0,
				["BannedUntilYear"] = 0,
				["BannedUntilMonth"] = 0,
				["BannedUntilDay"] = 0,
				["TotalBans"] = 0,
				["LastDate"] = os.date(),
				["LastEpoch"] = os.time(),
				["CurrentTitle"] = 0,
				["Inventory"] = {0}
			}
		end

		sessionData[newPlayer.UserId] = playerData

	else
		warn("Unable to get data for"..newPlayer.UserId)
		newPlayer:Kick("Unable to load player data, try again later")
	end

	if sessionData[newPlayer.UserId].Banned == true then
		if sessionData[newPlayer.UserId].BannedUntil == 0 then
			newPlayer:Kick("You are BANNED forever, reason: " .. sessionData[newPlayer.UserId].BannedReason)
		else
			if os.time() > os.time{year=sessionData[newPlayer.UserId].BannedUntilYear, month=sessionData[newPlayer.UserId].BannedUntilMonth, day=sessionData[newPlayer.UserId].BannedUntilDay} then
				sessionData[newPlayer.UserId].TotalBans = sessionData[newPlayer.UserId].TotalBans + 1
			else

				newPlayer:Kick("You are BANNED until "..sessionData[newPlayer.UserId].BannedUntilYear.."/"..sessionData[newPlayer.UserId].BannedUntilMonth.."/"..sessionData[newPlayer.UserId].BannedUntilDay..", reason: " .. sessionData[newPlayer.UserId].BannedReason)
			end
		end
	end
	local inv = HttpService:JSONDecode(sessionData[newPlayer.UserId].Inventory)
	if inv then
		sessionData[newPlayer.UserId].Inventory = inv
	else
		sessionData[newPlayer.UserId].Inventory = {}
	end

	sessionData[newPlayer.UserId].TotalJoins = sessionData[newPlayer.UserId].TotalJoins + 1 
	sessionData[newPlayer.UserId].LastDate = os.date()
	sessionData[newPlayer.UserId].LastEpoch = os.time()

	if GroupRank(newPlayer,255) then
		GiveInvItem(newPlayer,2)
		GiveInvItem(newPlayer,8)
	end
	if GroupRankGreater(newPlayer,254) then
		if not sessionData[newPlayer.UserId].GotAdminTitle then
			GiveInvItem(newPlayer,4)
			sessionData[newPlayer.UserId].GotAdminTitle = true 
		end
	end
	if GroupRankGreater(newPlayer,0) then
		if not sessionData[newPlayer.UserId].GotGroupTitle then
			GiveInvItem(newPlayer,5)
			sessionData[newPlayer.UserId].GotGroupTitle = true
		end

	end
	local PlayerBoughtGun =  MarketPlaceService:UserOwnsGamePassAsync(newPlayer.UserId, 272513764)
	if PlayerBoughtGun then
		GiveInvItem(newPlayer,11)
	end
	while true do
		if newPlayer.Character ~= nil then break end
		wait(5)
	end


	local humanoid = newPlayer.Character.Humanoid



	stats.Parent = newPlayer
	cash.Value = sessionData[newPlayer.UserId].Cash

end
game.Players.PlayerAdded:Connect(function(player)
	onPlayerEntered(player)
	UpdatePlayerTitle(player)
end)


function PlayerLeaving(player)
	if sessionData[player.UserId] then
		local success = nil
		local errorMsg = nil
		local attempt = 1
		sessionData[player.UserId].Inventory = HttpService:JSONEncode(sessionData[player.UserId].Inventory)
		repeat 
			success, errorMsg = pcall(function()
				database:SetAsync(player.UserId, sessionData[player.UserId])
			end) 	

			attempt += 1
			if not success then
				warn(errorMsg)
				task.wait(3)
			end
		until success or attempt == 5

		if success then
			print("Data saved for ", player.Name)
		else
			warn("Data unable to be saved for ", player.Name)
		end
	end
end
game.Players.PlayerRemoving:Connect(PlayerLeaving)

function ServerShutdown()
	if RunService:IsStudio() then
		return
	end
	print("saving all data due to server shutdown")
	for i, player in ipairs(players:GetPlayers()) do
		task.spawn(function()
			PlayerLeaving(player)
		end)
	end
end
game:BindToClose(ServerShutdown)
ReplicatedStorage.Events.RequestInventory.OnServerInvoke = function(player)
	if sessionData[player.UserId].Inventory then
		return sessionData[player.UserId].Inventory
	end
	return 404
end
ReplicatedStorage.Events.ExperiencedMapChange.Event:Connect(function(player: Player)
	if sessionData[player.UserId] then
		sessionData[player.UserId].TotalMaps = sessionData[player.UserId].TotalMaps + 1
		GiveCash(player,10)
	end
end)

ReplicatedStorage.Events.ExperiencedDisaster.Event:Connect(function(player: Player)
	if sessionData[player.UserId] then
		sessionData[player.UserId].TotalDisasters = sessionData[player.UserId].TotalDisasters + 1
	end
end)
ReplicatedStorage.Events.SurvivedDisaster.Event:Connect(function(player: Player)
	if sessionData[player.UserId] then
		sessionData[player.UserId].TotalDisasters = sessionData[player.UserId].SurvivedDisasters + 1
		GiveCash(player,5)
	end
end)
ReplicatedStorage.Events.EquiptTool.OnServerEvent:Connect(function(player: Player, key2) 
	if sessionData[player.UserId] then
		local inv = sessionData[player.UserId].Inventory
		for key,itemID in pairs(inv) do
			local item = itemData[itemID]
			if key == key2 then


				if item["Type"] == "Item" then
					item["Tool"]:clone().Parent = player.Backpack
				else if item["Type"] == "Title" then
						local char = player.Character
						local title = char.Head:FindFirstChild("PlayerTitle")
						if title then
							title:destroy()
						end
						local title = ReplicatedStorage.Assets.PlayerTitle:Clone()
						title.TextLabel.Text = item["Text"]
						title.TextLabel.TextColor = BrickColor.new(item["Col"])
						if char then
							title.Parent = char.Head
						end
					end
				end
			end

		end
	end
end)
ServerStorage.Events.PermBan.Event:Connect(function(playername,reason:string)
	local plrid = players:GetUserIdFromNameAsync(playername)
	local player = players:GetPlayerByUserId(plrid)
	print(playername)
	print(reason)
	print(plrid)
	print(player)
	if player then
		sessionData[plrid].BannedUntil = 0
		sessionData[plrid].BannedReason = reason
		sessionData[plrid].Banned = true
		player:Kick("You are BANNED forever, reason: " .. reason)
	end

end)

i dont understand, does it like save the data when you leave, but fails to load it back when you join?
if so there might be an issue while handling the data when the user joins, u might need to debug ur code

for some reason its a string after it loads, i just printed the session data

["Inventory"] = "[2,8,4,5,11]"