Error reference
Roblox: “Infinite yield possible on …”
This one is worse than an error, because it is only a warning. Your script did not crash — it stopped, permanently, at that line. Everything below it will never run, nothing turns red, and the bug presents as a button that simply does nothing.
What it means: a WaitForChild has been waiting more than five seconds. Roblox prints the warning once and keeps waiting. pcall will not catch it, error handlers will not fire, and the thread stays parked until the place shuts down.
The fix that applies in every case
Pass a timeout and handle the failure. This turns a silent hang into a message you can act on.
-- hangs forever if MainGui never arrives
local gui = playerGui:WaitForChild("MainGui")
-- returns nil after 10 seconds so the script can react
local gui = playerGui:WaitForChild("MainGui", 10)
if not gui then
warn("MainGui never replicated — is the server creating it for this player?")
return
end
A timeout is not a fix for the underlying cause, but it converts an invisible failure into a visible one — and on a live server that is the difference between a bug report you can act on and a player saying “the shop is broken sometimes”.
Why it never arrives
- Name or case is wrong. WaitForChild("mainGui") waits forever for something called MainGui. Lookups are exact.
- Wrong parent. The script assumes a flat layout, someone moved the object into a folder, and the wait is now aimed at the wrong place.
- It only exists on the server. Nothing in ServerStorage or ServerScriptService replicates to a client, so a LocalScript waits on it indefinitely.
- The script that creates it died first. If an earlier error killed the creating script, the object never gets made — read the first error in Output, not this warning.
- Streaming has not loaded it. With StreamingEnabled, distant parts of the world are not there yet, and may never be while the player stands where they are.
- You are waiting too deep. :WaitForChild("Frame") on an object whose parent has not arrived yet cannot succeed. Wait down the chain, one level at a time.
A pattern that cannot hang
local function waitForPath(root, path, timeout)
local current = root
local deadline = os.clock() + (timeout or 10)
for _, name in path do
local remaining = deadline - os.clock()
if remaining <= 0 then return nil, name end
current = current:WaitForChild(name, remaining)
if not current then return nil, name end
end
return current
end
local frame, missing = waitForPath(playerGui, { "MainGui", "Shop", "Frame" }, 10)
if not frame then
warn(("shop UI never loaded — stopped waiting at %q"):format(missing))
return
end
The useful part is missing: it tells you exactly which link in the chain is absent, which is the answer you actually wanted from the original warning.
Why this shows up so much in AI-written code
Generated Luau reaches confidently into hierarchies it has never seen. The names are plausible, the structure is plausible, and the code reviews perfectly — it just does not match your game. Worse, because an infinite yield is not an error, a model that “verifies” its work by checking that nothing went red will report success on a script that is frozen at line three. The runtime failure guide covers the same class of problem for blocking calls, and attempt to index nil is what you get when the same guess fails loudly instead of quietly.
A clean Output is not the same as a working game
Baseplate's playtest loop runs your game through a live Studio session and checks the actual behaviour, not just the absence of red text. Free plan, your own AI account.
Download Baseplate free