Issue with Checkpoints Script Teleporting Players Twice

I’m currently working on a Roblox game where I have created a script for checkpoints that should teleport players to the next stage. However, I’m encountering an issue where players are being teleported twice when they respawn. I need help troubleshooting this issue and fixing my script.

What’s happening:

When a player respawns, the script teleports them to the correct checkpoint, but then immediately teleports them again. This causes the player to be teleported twice. And there is a delay between the 2 teleports. So you are able to move for like a sec then it teleports you back to the checkpoint.

This is my script for the player stage to go up when they touch it which is in each check point

local Stages = workspace:WaitForChild("Stages")

for i,Stage in pairs(Stages:GetChildren()) do

	Stage.Touched:Connect(function(touch)

		local humanoid

		if touch.Parent:FindFirstChild("Humanoid") then

			humanoid = touch.Parent.Humanoid
		end

		if touch.Parent and touch.Parent.Parent:FindFirstChild("Humanoid") then

			humanoid = touch.Parent.Parent.Humanoid
		end

		if humanoid then

			local player = game.Players:GetPlayerFromCharacter(humanoid.Parent)

			local PlayerStage = player.leaderstats.Stage.Value

			if tonumber(Stage.Name) == PlayerStage + 1 then

				player.leaderstats.Stage.Value = player.leaderstats.Stage.Value + 1

			elseif tonumber(Stage.Name) > PlayerStage + 1 then

				humanoid.Health = 0
			end
		end
	end)
end

This is my script in ServerScriptService for leaderstats

local checkpoints = workspace:WaitForChild("Checkpoints")

game.Players.PlayerAdded(function(player)
	local leaderstats = Instance.new("Folder")
	leaderstats.Name = "leaderstats"
	leaderstats.Parent = player

	local stage = Instance.new("IntValue")
	stage.Name = "Stage"
	stage.Value = 1
	stage.Parent = leaderstats

	player.CharacterAdded:Connect(function(char)
		local hum = char:WaitForChild("Humanoid")
		wait()
		char:MoveTo(checkpoints[stage.Value].Position)

		hum.Touched:Connect(function(hit)
			if hit.Parent == checkpoints then
				if tonumber(hit.Name) == stage.Value + 1 then
					stage.Value = stage.Value + 1
				end
			end
		end)
	end)
end)

This is my script in ServerScriptService for the data

local Players = game:GetService("Players")
local DataStoreService = game:GetService("DataStoreService")
local SaveDataStore = DataStoreService:GetDataStore("SaveData")


local function SavePlayerData(player)

	local success,errormsg = pcall(function()

		local SaveData = {}

		for i,stats in pairs(player.leaderstats:GetChildren()) do

			SaveData[stats.Name] = stats.Value
		end 
		SaveDataStore:SetAsync(player.UserId,SaveData)
	end)

	if not success then 
		return errormsg
	end   
end 


Players.PlayerAdded:Connect(function(player)

	local Stats = Instance.new("Folder")
	Stats.Name = "leaderstats"
	Stats.Parent = player

	local Stage = Instance.new("StringValue")
	Stage.Name = "Stage"
	Stage.Parent = Stats
	Stage.Value = 1

	local Data = SaveDataStore:GetAsync(player.UserId)

	if Data then

		print(Data.Stage)

		for i,stats in pairs(Stats:GetChildren()) do

			stats.Value = Data[stats.Name]  
		end   
	else  
		print(player.Name .. " has no data.")   
	end


	player.CharacterAdded:Connect(function(character)

		local Humanoid = character:WaitForChild("Humanoid")
		local Torso = character:WaitForChild("HumanoidRootPart")

		wait()

		if Torso and Humanoid then
			if Stage.Value ~= 0 then

				local StagePart = workspace.Stages:FindFirstChild(Stage.Value)
				Torso.CFrame = StagePart.CFrame + Vector3.new(0,1,0)     
			end 
		end 
	end)  
end)


Players.PlayerRemoving:Connect(function(player)

	local errormsg = SavePlayerData(player)

	if errormsg then 
		warn(errormsg)  
	end 
end)

game:BindToClose(function()
	for i,player in pairs(Players:GetPlayers()) do 

		local errormsg = SavePlayerData(player)
		if errormsg then
			warn(errormsg)
		end   
	end
	wait(2) 
end)