Infinite Yield Possible on WaitForChild()

Heyo everyone!

Currently at my game, a few players (really a minority but its still making server errors)
are getting Infinite Yield on WaitForChild() of my RankContainer.

This is the code:

   local Players = game:GetService("Players")

local Overhead = script:WaitForChild("PlayerOverhead")
local Ranks = require(script:WaitForChild("Ranks"))

local OwnerId = 2641744211

local function EditPlayerRank(Player: Player, Overhead: BillboardGui)
	local leaderstats = Player:FindFirstChild("leaderstats")
	
	if leaderstats then
		
		local RankContainer = Overhead:WaitForChild("RankContainer", 60)
		if not RankContainer then
			warn("RankContainer not found in Overhead for player " .. Player.Name)
			return
		end
		
		local RankLabel = RankContainer:FindFirstChild("RankLabel")
		if not RankLabel then
			warn("RankLabel not found in RankContainer for player " .. Player.Name)
			return
		end
		
		if Player.UserId == OwnerId then
			RankLabel.Text = "Owner"

			local CurrentGradient = RankLabel:FindFirstChildOfClass("UIGradient")

			if CurrentGradient then
				CurrentGradient:Destroy()
			end

			local ColorGradient = script.RanksGradients:FindFirstChild("Owner")

			if ColorGradient then
				RankLabel.TextColor3 = Color3.new(1, 1, 1)
				ColorGradient:Clone().Parent = RankLabel
			else
				RankLabel.TextColor3 = Color3.new(0, 0, 0)
			end
		else
			for _, RankInfo in ipairs(Ranks) do
				if leaderstats["Purchases"].Value >= RankInfo.Purchases and leaderstats["R$ Spent"].Value >= RankInfo.Spent then
					RankLabel.Text = RankInfo.Rank
					local CurrentGradient = RankLabel:FindFirstChildOfClass("UIGradient")

					if CurrentGradient then
						CurrentGradient:Destroy()
					end

					local ColorGradient = script.RanksGradients:FindFirstChild(RankInfo.Rank)

					if ColorGradient then
						RankLabel.TextColor3 = Color3.new(1, 1, 1)
						ColorGradient:Clone().Parent = RankLabel
					else
						RankLabel.TextColor3 = Color3.new(0, 0, 0)
					end

					break
				end
			end
		end
	end
end

local function InsertOverhead(Player: Player, Character: Model)
	local newOverhead = Overhead:Clone()
	newOverhead.Parent = workspace[Player.Name].Head
	--newOverhead.Adornee = Target
	newOverhead.NameContainer.NameLabel.Text = Player.DisplayName or Players.Name

	EditPlayerRank(Player, newOverhead)

	local leaderstats = Player:FindFirstChild("leaderstats")

	leaderstats["Purchases"].Changed:Connect(function()
		EditPlayerRank(Player, newOverhead)
	end)

	leaderstats["R$ Spent"].Changed:Connect(function()
		EditPlayerRank(Player, newOverhead)
	end)
end

Players.PlayerAdded:Connect(function(Player)
	Player.CharacterAdded:Connect(function(Character)
		task.wait(3)
		local Humanoid = Character:WaitForChild("Humanoid")

		Humanoid.ChildAdded:Connect(function(Child)
			if Child:IsA("HumanoidDescription") then
				InsertOverhead(Player, Character)
			end
		end)

		InsertOverhead(Player, Character)
	end)
end)

I can’t figure out what else to do. I even made a check, after the issues were occuring, to give me a warning on what player its not finding RankContainer.

I have to mention that my game is around Outfits, and I might think this is related to that, when a player wears an outfit, the humanoidDescription is changed, which can change the head. However, at the end of the script, that is already checked, and it works for most players.

All the childs exist, everything works perfectly for most players (including myself) so I can’t figure out why its warning for this minority.

Can this be related to Ping/Device not being able to inset the Overhead GUI? Should I ignore it, since it doesn’t affect most players, or try to fix it?

Thanks!

2 Likes

Can you please send an image of the actual error message?

Currently, after the if I made:

image

Before:
image

The amount of warnings were changed because my most recent versions didn’t have, so I had to search for a longer time period.
But its the same warning

So first off, unless you have two scripts that run different parts of the same script, those two errors aren’t related.
One is on the server, and the other, the client.

The rank container object could be getting removed by the server when the players character is loaded as sometimes the character is delayed & loads after the function gets sent, which removes the gui

Even tho one displays as Client and the other as Server, they are both at Server (Roblox might be mistakening it)
When I joined the servers, at some point, there would be this error at Server logs.
And this is the only Script messing with it.

If thats the case, wouldn’t it remove the Overhead aswell? Since it’s his Parent?
If so, what would be a possible fix?

Alright
Where does the rank container get created?

Also must say that the problem is on the function EditPlayerRank, at least before I added the WaitForChild(“RankContainer”), it was printing this error:

Was that error appearing every time?

The Overhead Clone is made at the function InsertOverhead , which already contains RankContainer as a Child

Not at all, also was only appearing for a very few players.
It was happening for one player, at a certain period of time (I would say happening for 1 player in every 100 players), but it would print it multiple times, making it occuring 137 thousand in a month.
Infinite Yield is also only happening in the same logic

The infinite yield must be coming from another script, I read your code and I couldn’t find PlayerOverhead:WaitForChild("RankContainer")

Do you have any other scripts that alter the rank?

Its at the very start of the script :sweat_smile:

The overhead is called PlayerOverhead:

Oh my bad, I read it and thought it was talking about what it was defined as inside of the script

This is the path
image

I’m not 100% certain of what could be causing it, but the best guess that I could give is that the rank container/overhead ui is being removed (or renamed) before the script is able to find it.

What I could suggest for you to do, is add a few more lines of code which checks if the overhead ui is a valid object & check it’s children

The AI told me this and I seems to explain your edge case:
You’re waiting for a HumanoidDescription to be added to the Humanoid before calling InsertOverhead. However, it’s possible that the HumanoidDescription is added before your ChildAdded event is connected, which would mean InsertOverhead is never called in response to the HumanoidDescription. To fix this, you could check if the HumanoidDescription exists before connecting the event.

did you try:

:WaitForChild(Instance, 1) -- with n after

Alright, I have implemented that.
I also at InsertOverhead changed from it adding to workspace.head to Player.Character.head to see.
In about an Hour, I will give updates if the error is continuing

Infinite yield is not necessarily an error, a warning. I know you know its a warning but hear me out, many games have the same issue as you. Let me give you an example, lets say you have a script in startercharacterscripts. And you have a tool.Activated event in it, u need to use a waitforchild to access that tool in the character cuz sometimes it can be in the backpack. But it’ll show an infinite yield warning.

Actually you might be correct.
I somehow managed to get the error on an alt account, and everything was working just fine and still printed that it wasn’t the warning.