Guides
Fix Common Luau Errors
Eight error messages almost every Roblox scripter meets — what they mean, and the fix. Bookmark this page for when Studio yells at you.
Error messages look scary, but they're actually a map to the bug. Every message names what went wrong and usually which line. If you can read one, you can fix it. These are the ones you'll hit first — all of them are covered in detail inside the free course lessons.
Attempt to index nil with “Position”
Attempt to index nil with “Position”The code that triggers it:
local part = workspace.MyPart
print(part.Position)`MyPart` doesn’t exist yet — or doesn’t exist under that exact name. When a part isn’t in the Workspace, `workspace.MyPart` is `nil`, and you can’t read a property off nothing.
The fix:
local part = workspace:WaitForChild("MyPart")
print(part.Position)`WaitForChild` pauses the script until the part exists. This is the standard fix for anything that loads in later — like a player’s character or an item you clone in. See the Workspace and parts lesson teaches the concept properly.
Attempt to perform arithmetic (add) on nil value
Attempt to perform arithmetic (add) on a nil valueThe code that triggers it:
local coins
coins = coins + 10
print(coins)`coins` was declared but never given a starting value, so it’s `nil`. Adding 10 to nothing isn’t allowed.
The fix:
local coins = 0
coins = coins + 10
print(coins)Give the variable a real starting value. `0` for numbers, `false` for booleans, and `{}` for tables. The variables lesson teaches the concept properly.
Attempt to call a nil value
Attempt to call a nil valueThe code that triggers it:
makeCoins()You’re calling a function that doesn’t exist. Either it hasn’t been defined yet (scripts run top to bottom), or the name is spelled differently somewhere.
The fix:
local function makeCoins()
return 5
end
print(makeCoins())Define the function before you call it, and check the spelling matches exactly. The functions lesson teaches the concept properly.
Undefined global “coin”
Undefined global “coin”The code that triggers it:
local coins = 0
coins = coins + 10
print(coin)A typo — you wrote `coin`, but the variable is `coins`. Roblox Studio warns you about globals you never declared, which catches exactly this kind of mistake.
The fix:
local coins = 0
coins = coins + 10
print(coins)Use `local` for every variable and let Studio’s warning point at the misspelled name. The naming variables lesson teaches the concept properly.
Expected “end” (to close a block)
Expected “end” (to close a block) at line 5The code that triggers it:
if coins > 10 then
print("Rich!")
-- the "end" is missingEvery `if`, `function`, `for`, and `while` has to be closed with an `end`. The error tells you exactly which line the block opened on, so look there first.
The fix:
if coins > 10 then
print("Rich!")
endMatch every opening keyword with an `end`. Formatting with consistent indentation makes missing ones obvious. The conditionals lesson teaches the concept properly.
Infinite yield possible
Infinite yield possible on “workspace:WaitForChild(“MyPart”)”The code that triggers it:
local part = workspace:WaitForChild("MyPart")A warning, not an error — `WaitForChild` waited a while and the thing still doesn’t exist. Often the name is wrong, or the part never loads in this script’s context.
The fix:
local part = workspace:FindFirstChild("MyPart")
if part then
print(part.Name)
endUse `FindFirstChild` and check for `nil` when you’re not sure the object exists. For things that genuinely load later, `WaitForChild` is still the right tool — just double-check the name. The instances lesson teaches the concept properly.
The server is not currently using… / nil LocalPlayer
Players.LocalPlayer is nilThe code that triggers it:
-- in a server (Script) object
local player = game.Players.LocalPlayer
print(player.Name)`LocalPlayer` only exists on the client. A server script can’t see it — there’s no single “your” player from the server’s point of view.
The fix:
game.Players.PlayerAdded:Connect(function(player)
print(player.Name)
end)On the server, react to `PlayerAdded` instead. The same rule explains most “cant find X here” bugs: match your code to where it runs. The RemoteEvents lesson teaches the concept properly.
Attempt to index nil with “Humanoid” (character)
Attempt to index nil with “Humanoid”The code that triggers it:
local player = game.Players.PlayerAdded:Wait()
local humanoid = player.Character.HumanoidA player’s character isn’t loaded yet — it spawns a moment after they join. Reading `.Character` right away gives you `nil`.
The fix:
local function onCharacter(player)
player.CharacterAdded:Connect(function(character)
local humanoid = character:WaitForChild("Humanoid")
print(humanoid.Health)
end)
end
game.Players.PlayerAdded:Connect(onCharacter)Wait for `CharacterAdded`, then `WaitForChild("Humanoid")`. The characters lesson teaches the concept properly.
When the fix isn't obvious
If an error is still confusing, don't guess — read the error, then narrow it down. The debugging lesson teaches a step-by-step method for reading errors like a pro, and print debugging shows how to watch your code run line by line.
Practice without pressure
The course includes bug-hunt exercises where you deliberately fix broken code — the fastest way to make these errors feel familiar instead of frightening.