Pathfinding on terrain seems to break? Works fine on flat surface parts. What would be a good solution?

I’m working on AI for enemies in my game. However, with terrain, it seems to break the pathfinding.

Below is a video of when the pathfinding error occurs. Note that this doesn’t happen and the pathfinding is fine on any flat surface, if I place a floor as a part, the pathfinding works.

Below is the entire code for my skeleton. This includes animations & sounds.

local npc = script.Parent
local human = npc.Humanoid
local rootPart = script.Parent.HumanoidRootPart

local PFS = game:GetService("PathfindingService")
local RUNSERVICE = game:GetService("RunService")
local PLAYERS = game:GetService("Players")
local animator = human:FindFirstChildOfClass("Animator")

local attackAnimation1 = human:LoadAnimation(game.ReplicatedStorage.Animations.Enemy.Skeleton:WaitForChild("attack1"))
local deathAnimation1 = human:LoadAnimation(game.ReplicatedStorage.Animations.Enemy.Skeleton:WaitForChild("death1"))
local runAnimation1 = human:LoadAnimation(game.ReplicatedStorage.Animations.Enemy.Skeleton:WaitForChild("run1"))
local idleAnimation1 = human:LoadAnimation(game.ReplicatedStorage.Animations.Enemy.Skeleton:WaitForChild("idle1"))
local stuns = game.ReplicatedStorage.Animations.Enemy.Skeleton.Stuns:GetChildren()
	
local damage = 50
local lastHealth = human.Health
local hitboxL = npc:FindFirstChild("HitboxL")
local hitboxR = npc:FindFirstChild("HitboxR")
local deathSound = script.Parent.HumanoidRootPart.Death
local attackSounds = script.Parent.Jaw:GetChildren()
local trailL = npc.TrailL.Trail
local trailR = npc.TrailR.Trail
local bones = npc.HumanoidRootPart.Bones

local D = true
local SD = true
local enemymodel = npc:WaitForChild("HumanoidRootPart")

npc.PrimaryPart:SetNetworkOwner(nil)


--Hit Sounds
local hit1 = script.Parent.HumanoidRootPart.HitBone1
local hit2 = script.Parent.HumanoidRootPart.HitBone2
local hit3 = script.Parent.HumanoidRootPart.HitBone3

local hits = {
	hit1,
	hit2,
	hit3
}

--Stun Settings
local function playRandomHitSound()
	if #hits > 0 then
		local randomSound = hits[math.random(1, #hits)]
		randomSound:Play()
	end
end

local function playRandomAttack()
	if #attackSounds > 0 and CD == true and human.Health > 0 then
		local randomAttack = attackSounds[math.random(1, #attackSounds)]
		randomAttack:Play()
	end
end

local function onFirstKeyframeReached1()
	trailL.Enabled = true
	trailR.Enabled = true
	CD = true
	playRandomAttack()
end

local function onSecondKeyframeReached1()
	trailL.Enabled = false
	trailR.Enabled = false
	CD = false
end

local function onKeyframeReached()
	bones:Play()
end

attackAnimation1:GetMarkerReachedSignal("damage1"):Connect(onFirstKeyframeReached1)
attackAnimation1:GetMarkerReachedSignal("damage2"):Connect(onSecondKeyframeReached1)

deathAnimation1:GetMarkerReachedSignal("bones1"):Connect(onKeyframeReached)

local function onPartTouched1(otherPart)
	local character = otherPart.Parent
	local humanoid = character:FindFirstChild("Humanoid")
	if humanoid then
		if CD == true then
			humanoid:TakeDamage(damage)
				CD = false
		end
	end
end

local function onPartTouched2(otherPart)
	local character = otherPart.Parent
	local humanoid = character:FindFirstChild("Humanoid")
	if humanoid then
		if CD == true then
			humanoid:TakeDamage(damage)
			CD = false
		end
	end
end

hitboxL.Touched:Connect(onPartTouched1)
hitboxR.Touched:Connect(onPartTouched2)

local function findTarget()
	local players = PLAYERS:GetPlayers()
	local nearesttarget
	local maxDistance = 50 -- distance

	for i, player in pairs(players) do
		if player.Character then
			local target = player.Character
			local distance = (npc.HumanoidRootPart.Position - target:WaitForChild("HumanoidRootPart").Position).Magnitude

			if distance < maxDistance then
				nearesttarget = target
				maxDistance = distance
			end
		end
	end
	return nearesttarget
end

local function getPath(destination)
	local path = PFS:CreatePath()

	path:ComputeAsync(npc.HumanoidRootPart.Position, destination)

	return path
end

local function pathFindTo(destination)
	local path = getPath(destination)
	local target = findTarget()

	if target and target.Humanoid.Health > 0 then
		for i, waypoint in pairs(path:GetWaypoints()) do
			human:MoveTo(waypoint.Position)
			human.MoveToFinished:Wait()
		end
	end
end

local function onDeath()
	-- Find the player who killed the NPC
	local killer = human:FindFirstChildOfClass("ObjectValue")
	if killer and killer.Name == "creator" and killer.Value then
		local player = killer.Value
		local leaderstats = player:FindFirstChild("leaderstats")
		if leaderstats then
			local fame = leaderstats:FindFirstChild("Fame")
			if fame then
				fame.Value = fame.Value + 10
			end
			local Gold = leaderstats:FindFirstChild("Gold")
			if Gold then
				Gold.Value = Gold.Value + 3
			end
		end
	end
end

human.Died:Connect(onDeath)

RUNSERVICE.Heartbeat:Connect(function()
	local target = findTarget()

	if target then
		local stopDistance = 3 -- Stop 5 studs away from target
		local targetPosition = target:WaitForChild("HumanoidRootPart").Position
		local directionToTarget = (targetPosition - npc.HumanoidRootPart.Position).Unit
		local stopPosition = targetPosition - directionToTarget * stopDistance

		local distanceToTarget = (npc.HumanoidRootPart.Position - targetPosition).Magnitude

		if distanceToTarget <= 5 and D == true and human.Health > 0 then
			npc:SetPrimaryPartCFrame(CFrame.lookAt(npc.HumanoidRootPart.Position, targetPosition))
			human.WalkSpeed = 0
			attackAnimation1:Play()
			D = false
			task.wait(3)
			D = true
			human.WalkSpeed = 10
		else
			human.WalkSpeed = 10
			pathFindTo(stopPosition)
		end
	end
end)

local function onNPCDied()
	local Eye1 = script.Parent.Accessories.EyeL.Glow
	local Eye2 = script.Parent.Accessories.EyeR.Glow
	local Glow = script.Parent.Accessories.Glow.PointLight
	rootPart.Anchored = true
	deathSound:Play()
	Eye1.Enabled = false
	Eye2.Enabled = false
	Glow.Enabled = false
	deathAnimation1:Play()
	task.wait(deathAnimation1.Length)
	npc:Destroy()
end

--Stun Settings
local function playRandomStunAnimation()
	if #stuns > 0 and SD == true then
		local randomStun = animator:LoadAnimation(stuns[math.random(1, #stuns)])
		SD = false
		randomStun:Play()
		human.WalkSpeed = 0
		human.JumpPower = 0
		playRandomHitSound()
		task.wait(.4)
		SD = true
		human.WalkSpeed = 10
		human.JumpPower = 45
	end
end

human.HealthChanged:Connect(function(health)
	if health < lastHealth then
		playRandomStunAnimation()
	end
	lastHealth = health
end)

--End Death
human.Died:Connect(onNPCDied)

What are some solutions would you think would help with this glitch? Should I move away from terrain? If so, what are some good ways to create worlds with parts?

Have you tried turning it on and off again?