How to Fix 'Infinite yield possible on WaitForChild' in Roblox
Quick answer: 'Infinite yield possible on WaitForChild("X")' means the child named X never appeared under the parent you searched after several seconds, so your script is stuck waiting. Fix it by checking the exact name and case, confirming the correct parent path, and passing a timeout argument with a nil check so the script can recover instead of hanging forever.
The "Infinite yield possible on WaitForChild" message means your script called :WaitForChild() on an instance whose child never showed up within the engine's warning window (about five seconds), so the thread is still paused waiting for a descendant that may never arrive. It is a warning, not an error — the script does not crash, but it hangs on that line indefinitely, and everything below it never runs.
What does "Infinite yield possible" actually mean?
Instance:WaitForChild(name)** yields the current thread until a child called name` exists under the parent. If the child is already there, it returns instantly. If not, Roblox waits — and if nothing appears after roughly five seconds, the engine prints:
-- Example that triggers the warning:
local part = workspace:WaitForChild("SpawnPoint") -- no child named SpawnPoint
The exact output looks like this in the console:
Infinite yield possible on 'Workspace:WaitForChild("SpawnPoint")'
Two things matter about this message:
- It is a warning, not an error. Your script did not fail or throw. The thread is simply still suspended.
- Your script is hung. Every line after the
WaitForChildcall never executes while the wait continues. In practice, players experience this as a broken feature: a GUI that never loads, a round system that never starts, a shop that never opens.
Why is my WaitForChild never finding the child?
Almost every infinite-yield warning comes down to one of three causes.
The name is misspelled or the case is wrong
WaitForChild matches child names exactly, including capitalization. workspace:WaitForChild("spawnpoint") will never find a part named SpawnPoint. This also catches invisible characters: copying names from chat or documentation sometimes smuggles in trailing spaces or lookalike characters.
You are looking in the wrong parent
Calling player:WaitForChild("leaderstats") works only if leaderstats was parented to that player. If the server creates it somewhere else — or never created it at all because of a failed pcall earlier in the code — the client waits forever. Trace where the instance is actually created and confirm the full path from your variable to the object.
The instance is created later by replication or streaming
This cause trips up even careful scripters. On the client, objects created by the server do not exist until they replicate over the network, so a LocalScript running immediately may legitimately need to wait. With StreamingEnabled, parts of a character can be streamed out and back in as the camera moves, meaning even instances like a character's hat or tools can vanish and reappear. Waiting here is correct behavior — the bug is waiting without a plan for "what if it takes too long."
How do I fix the infinite yield warning?
Work through the causes in order.
First, verify the exact name and path
Print what actually exists instead of guessing:
for _, child in workspace:GetChildren() do
print(child.Name)
end
Compare the printed names character by character with the string in your WaitForChild call, then confirm the parent variable holds the instance you think it does (print(parent:GetFullName())). Most warnings die right here.
Then, add a timeout so the script can recover
The second argument of WaitForChild is a timeout in seconds. With a timeout, the call gives up after that many seconds and returns nil instead of yielding forever:
local spawnPoint = workspace:WaitForChild("SpawnPoint", 10)
if not spawnPoint then
warn("SpawnPoint never appeared under Workspace")
return
end
print("Found:", spawnPoint:GetFullName())
This pattern converts a silent hang into an explicit, debuggable failure. Use a generous timeout (5–15 seconds) when the child genuinely should appear soon — such as server-created leaderstats replicating to a new player — so slow connections are not penalized, but the script still bails out if something upstream broke.
When should I use FindFirstChild instead of WaitForChild?
:FindFirstChild(name) checks once, returns the child or nil immediately, and never yields. Prefer it when the child might legitimately not exist:
local tool = character:FindFirstChild("Sword")
if tool then
tool:Destroy()
end
Use FindFirstChild when absence is normal (checking whether a player owns something, polling in a loop) and reserve WaitForChild for children that must exist for the feature to work. A common hybrid is polling with FindFirstChild plus task.wait, which lets you run other logic between checks:
local target
while not target do
target = workspace:FindFirstChild("RoundArena")
if not target then
task.wait(0.5)
end
end
If you reach for FindFirstChild because WaitForChild warned, remember that swallowing the warning without fixing the missing child just moves the failure downstream — often into an "attempt to index nil" error, which we cover in how to fix attempt to index nil.
What about characters and StreamingEnabled?
Character models are the most frequent source of streaming-related waits. When a player spawns, the client may receive the Character reference before every descendant has replicated, and with StreamingEnabled distant parts stream out dynamically. Two safe habits:
- Wait on the model first, then check descendants non-blockingly or with a bounded timeout:
local function onPlayerAdded(player)
local character = player.Character or player.CharacterAdded:Wait()
local head = character:WaitForChild("Head", 5)
if not head then
warn(player.Name .. ": Head not replicated yet")
return
end
-- safe to use head
end
- Never assume any specific part exists inside a character; guard every access. For reacting to physical contact with character parts, see our guide on the Touched event, where the same streaming caveats apply to whatever hits your sensor.
Quick checklist
- Print the parent's children and match the name exactly, including case.
- Confirm the parent path — is the instance created under the object you think?
- Add a timeout argument and handle the
nilreturn withwarn+ early return. - Switch to
FindFirstChildwhere absence is a normal state, not a bug.
Waiting correctly is one small piece of writing scripts that behave predictably. If you want to build that instinct with hands-on practice rather than trial and error, the interactive lessons on Luablox cover yielding, events, and instance handling step by step — start at /theory, drill real bugs in the problems section, or follow the structured Luablox lessons from your browser.
Frequently asked questions
Is "Infinite yield possible on WaitForChild" an error?
No. It is a warning printed by Roblox when a WaitForChild call has been waiting for more than about five seconds. Your script does not crash, but the thread stays suspended on that line indefinitely, so everything below it stops executing until the child appears.
How do I stop WaitForChild from yielding forever?
Pass a timeout as the second argument, e.g. workspace:WaitForChild("Part", 10). After ten seconds it returns nil instead of waiting forever. Check for nil with an if statement and warn or return early so the failure is visible and debuggable.
Why would the child never appear at all?
Usually the name string is misspelled or has wrong capitalization, the parent variable points to a different instance than expected, or the instance is only created later by the server (or streamed in/out with StreamingEnabled) and something upstream prevented it from being created.
Should I use FindFirstChild instead of WaitForChild?
Use FindFirstChild when the child might legitimately not exist — it returns immediately with nil and never yields, so you can handle absence gracefully. Use WaitForChild (with a timeout) when the child must exist for the feature to work and you expect it to replicate shortly.
Does WaitForChild work reliably with StreamingEnabled?
It works, but streamed-out parts can disappear and reappear, so a part that existed once may not exist later. Wait for the character model first, then use bounded WaitForChild timeouts plus nil checks for individual body parts, and always guard access before using them.
Understand loop structures in Luau, including numeric, while, generic pairs, and ipairs iterators.