My script keeps choosing some mystery thing that doesn't exist?

--setting up previousPOI variable for later use
local previousPOI = nil


--choose a random POI for troops to move towards
function choosePOI(POIList, previousPOI)

	--choose a POI
	local chosenPOI = POIList[math.random(1, #POIList)]

	--make sure the troops are not already at the poi chosen; if so, find a new one
	if chosenPOI == previousPOI then
		choosePOI(POIList, previousPOI)
	else

		--if it is in fact a new POI, return it
		return chosenPOI

	end


end



--IN AN EVENT LATER ON TRIGGERED BY A VALUE--------------VVVV

--find the map
		local map = game.Workspace:FindFirstChild("Map")

		--get a random point of interest location
		local POIs = map:FindFirstChild("pointsOfInterest"):GetChildren()
		local chosenPOI = choosePOI(POIs, previousPOI)

previousPOI = chosenPOI


		

This works the majority of the time. Yet sometimes, it says "attempt to index nil with “position” (when I try to pathfind to this position later on).
So I decided to debug by printing the name of the part it’s pathfinding to. Here’s the image of the POIs for reference-
image
When it works, it prints “Part1” or “Part3”, you know.

When it doesn’t work, it just prints “nil”.
Where is nil coming from?

NOTE: My only idea is that my randomizer script somehow picks a number for an index in the list of POIs that doesn’t correspond to a value, giving me nil? But as far as I can tell, there’s literally nothing wrong with my code. I may be stupid, blind, and exhausted, so if it is that simple do tell!

Replace FindFirstChild with WaitForChild, because the parts in the game might have not loaded yet.

I guess a bit more context might’ve helped here, but I didn’t want the post to be too big and scare people off

This is in an event that is only triggered when I have a value changed- which I’ve been doing manually in my testing, long after everything has loaded, so I don’t think that’s the issue

Taking a quick look at you code. Your choosePOI function caught my eye. Specifically this part:

if chosenPOI == previousPOI then -- if this is true then you're returning nothing!!
		choosePOI(POIList, previousPOI) -- this refires the function but doesn't return anything to the original line that called it!!
	else

		--if it is in fact a new POI, return it
		return chosenPOI

	end

What’s happening is that when this statement runs and the chosenPOI == previousPOI all you do is just re-fire the function but you aren’t returning anything!

So this variables just ends up being nil:

local chosenPOI = choosePOI(POIs, previousPOI) -- is nil cause of above

The reason this is only occuring sometimes is because the chosePOI WASN’T equal to the previous one. There’s a couple of ways to fix this. Either you can brute force your way by running a repeat loop until the previousPOI isn’t equal to the new one.

OR

At the start of the choosePOI function → create a table with all the POI’s → simple remove the previousPOI from that table → you can then select a random POI like you normally would without having to worry if it was the previous one because you removed it! (I recommend this way!)

i actually found out that this is the issue, but an easier fix is instead of just recalling the function, return the recalled function as well, so like this

if chosenPOI == previousPOI then -- if this is true then you're returning nothing!!
		return choosePOI(POIList, previousPOI) -- this refires the function but doesn't return anything to the original line that called it!!
	else

		--if it is in fact a new POI, return it
		return chosenPOI

	end

Here is a non recursive method you can try:

function choosePOI(POIList, previousPOI)

	local size = #POIList
	local chosenPOI = POIList[math.random(1, size - 1)]
    POIList[size], POIList[chosenPOI] = POIList[chosenPOI], POIList[size]

    return POIList[size]
end