:WaitForChild infinite yield, even though the object I'm referencing exists

I’ve run into an issue where I’m trying to get something from the PlayerGui, but for some reason – even though in the hierarchy it shows it is there – :WaitForChild("bla") is infinitely yielding.

Data dump:


Infinite yield possible on 'BuildTool:WaitForChild("InformationPanel")'




local PLAYERS = game:GetService("Players")

--[[ GLOBALS ]]
-- These all work fine
local ConfigDisplay     = script:WaitForChild("ConfigDisplay")
local Spacer            = script:WaitForChild("Spacer")
local InfoDisplay       = script:WaitForChild("InfoDisplay")
local Layout            = script:WaitForChild("Layout")
local InfoDisplayLayout = script:WaitForChild("InfoDisplayLayout")
local LocalPlayer       = PLAYERS.LocalPlayer

-- this where we at
-- Adding wait(1) here fixes this, for whatever reason.
local GUI               = LocalPlayer.PlayerGui:WaitForChild("BuildTool")
                                               :WaitForChild("InformationPanel") -- This waitforchild, specifically


As you can see, InformationPanel definitely exists as a descendant of PlayerGui.BuildTool, but for some reason when I attempt to grab it with WaitForChild it yields infinitely.

If I call wait(1) before this line, it works, but I don’t know if it will work in all cases. Besides, WaitForChild is implied it will wait anyways, why do I have to call wait(1) for WaitForChild to work?

I believe there’s an engine bug here, but I can’t post to engine bugs yet.

Edit for clarification:

It’s not just displaying the warning then loading, it’s outright failing to “wait for” InformationPanel unless I add wait(1).

It’s just a warning that it’s possible, if adding wait(1) fixes it then that means it is taking time to load that’s all.

You must have a lot of assets/Instances in the place file for it to take time to load.

Consider avoiding wait for child by using this option by using game.Loaded and putting your GUI in rep storage.

if not game:IsLoaded() then

That’s the thing – It outright doesn’t load without the wait(1).

The infinite yield is quite literally infinite, unless I add wait(1), which makes no sense because WaitForChild should wait normally should it not? Adding wait(1) makes it load near instantly, whereas without wait(1) I let Studio idle for about 10 minutes and it still never finished loading the module (ie: it was still yielded).

You must have a lot of assets/Instances in the place file for it to take time to load.

Not really, no. I’ve got about 20 or 30 parts and 5 scripts.

Well I can’t replicate it got a place file to reproduce the bug? You will definitely need it if you want to make a proper engine bug report post.

Reproduction Steps

Provide step-by-step instructions that cause the bug to happen.
These steps must be:

  • Minimal - Simplify complicated steps or conditions as much as possible.
  • Specific - Steps must be clear and detailed. Don’t assume engineers know what you mean.
  • Consistent - Ideally, your steps reproduce the issue 100% of the time. Specifically mention how often your steps reproduce the bug (100% / 50% / Rarely?)
local LocalPlayer = game.Players.LocalPlayer

local GUI               = LocalPlayer.PlayerGui:WaitForChild("BuildTool")
:WaitForChild("InformationPanel") -- This waitforchild, specifically

print(GUI)--prints Main Area


1 Like

Currently attempting to figure out full repro steps, but I think it has something to do with the localscript being in PlayerScripts? Not 100% sure what’s going on internally there.

Have you tried :WaitForChild(“InformationPanel”, math.huge)?

Alright, so I deleted and deleted and deleted from my main .rbxl until I was down to a single LocalScript, ModuleScript, and ServerScript. From those scripts, I was able to narrow it down to the exact line that was causing this issue.

The problem

To understand what happened we first need to talk about parallel universes a very short version history of my project.

Originally, I was going to use a tool to build things, so all my scripts were inside this tool. Originally, I was going to create a custom death scene, this required me to manually call Player:LoadCharacter(). Both of these ideas I removed the other day in favour of using contextservice and throwing the scripts into the StarterPlayerScripts, and just adding a simple GUI on death respectively – resetting the player’s automatic respawn to true.

However, I forgot to remove the call to Player:LoadCharacter().

So now it turns into a timing issue. I’m able to get the player’s Gui, then wait for the first child, but then suddenly while waiting for the second child the player is force-respawned and the UI object is destroyed then remade. This means the WaitForChild is waiting for an object that is now destroyed, from an object that is destroyed. The script cannot continue.

The resolution

To fix this, I simply removed the call to Player:LoadCharacter() and added some listeners for the player respawning to reset the values I needed.

You can see it all in action from the barebones version of my game below.

BAREBONES.rbxl (35.6 KB)