Roblox Studio error

attempt to compare nil < number

What attempt to compare nil < number means in Roblox Studio, the three things that cause it with the code that triggers each, and the fix for each one.

Updated 23 October 20263 min readErrorLuau

In short

<, >, <= and >= need two numbers (or two strings). The message names the two types it got. nil < number means one side was missing: usually a value that was never set, a .Value you forgot, or text that needs tonumber. Note that Luau writes every comparison as < or <=, so coins >= price with a nil coins shows up as number <= nil.

On this page
  1. What it means
  2. Causes and fixes
  3. Fix it with RoCode
  4. Find the line
  5. Questions
  6. Sources

What the message means

Output (example)
ServerScriptService.Shop:18: attempt to compare nil < number

Other forms of the same message:

  • attempt to compare number < nil
  • attempt to compare string < number
  • attempt to compare nil <= number
  • attempt to compare Instance < number

Luau turns a > b into b < a before it runs it. That is why the message can list the sides in the opposite order from your code: read it as "one side was nil, the other a number", then check both.

== and ~= never cause this error. They work on any two values and simply give false or true.

Causes and fixes

Three things cause this error in practice. Each one below has the smallest code that triggers it, then the fix.

One side was never set (nil)

A value from a table, an attribute or a function that returned nothing is nil. A shop check like if coins >= price then fails for a player whose data has not loaded, or for an item with no price.

Breaks Script in ServerScriptService named Shop
local prices = { Sword = 100 }

local function canBuy(coins, item)
	-- "Bow" has no price: attempt to compare nil <= number
	return coins >= prices[item]
end

print(canBuy(150, "Bow"))

Check that both values exist before comparing, and decide what a missing one means.

Fixed Script in ServerScriptService named Shop
local prices: { [string]: number } = { Sword = 100 }

local function canBuy(coins: number, item: string): boolean
	local price = prices[item]
	if price == nil then
		warn(`[Shop] no price for {item}`)
		return false
	end
	return coins >= price
end

print(canBuy(150, "Bow"))

Text was compared with a number

A TextBox, an attribute or a string from a data store holds text. Unlike maths, comparisons never convert text, so "50" < 100 fails with string < number even though the text looks like a number.

Breaks LocalScript in a TextBox in StarterGui named Bet
local box = script.Parent

box.FocusLost:Connect(function()
	-- attempt to compare string < number
	if box.Text < 100 then
		print("small bet")
	end
end)

Convert with tonumber, and handle the case where it is not a number.

Fixed LocalScript in a TextBox in StarterGui named Bet
local box = script.Parent :: TextBox

box.FocusLost:Connect(function()
	local bet = tonumber(box.Text)
	if bet and bet < 100 then
		print("small bet")
	end
end)

A value object was compared instead of its number

leaderstats.Coins is an IntValue, not a number. Coins >= 50 compares an object with a number and fails with Instance in the message.

Breaks Script in ServerScriptService named Shop
local Players = game:GetService("Players")

Players.PlayerAdded:Connect(function(player)
	local coins = player:WaitForChild("leaderstats"):WaitForChild("Coins")
	-- attempt to compare number <= Instance
	if coins >= 50 then
		print("rich")
	end
end)

Compare .Value.

Fixed Script in ServerScriptService named Shop
local Players = game:GetService("Players")

Players.PlayerAdded:Connect(function(player: Player)
	local leaderstats = player:WaitForChild("leaderstats", 10)
	local coins = leaderstats and leaderstats:WaitForChild("Coins", 10)
	if coins and coins:IsA("IntValue") and coins.Value >= 50 then
		print("rich")
	end
end)

Fix it in your place

Paste the error, RoCode fixes it in your place

Copy the line from Output and paste it here. RoCode opens the script it names in the place you have open in Studio, works out which of the causes above it is, and edits the code there instead of handing you a snippet to paste.

For example: ServerScriptService.Shop:18: attempt to compare nil < number

RoCode is an AI agent for Roblox Studio: it reads the scripts in the place you have open, finds the line and edits it there, and every change is an undo point. It runs on Windows or macOS with a desktop browser. Free to start, with free credits every day.

How to find the line that causes it

  1. Open Output (Window menu, or the Script tab), clear it with Ctrl+K (⌘K on Mac), and press Play.
  2. Find the first red line. It starts with the script's place in the Explorer and the line number, such as ServerScriptService.Shop:12:.
  3. Click the red line. Studio opens that script with the cursor on the failing line.
  4. Read the lines between Stack Begin and Stack End under it: they list the calls that led there, newest first, so you can see which function called the broken one.
  5. Still not sure which value is wrong? Add print(typeof(x), x) just above the line, or set a breakpoint on it and read the values in the Watch window.

Questions

Why does the message show the sides in the wrong order?

Luau runs every greater-than check as a less-than check with the two sides swapped, so a >= b runs as b <= a. The message describes what actually ran, so the nil can appear on the other side from your code.

Why does "50" + 1 work but "50" < 100 fail?

Luau converts number-like text in maths, but never in comparisons. Use tonumber before comparing.

Can I compare two strings?

Yes, "apple" < "banana" compares them alphabetically. The error only comes when the two sides are different types, or a type that cannot be ordered, such as nil, a boolean or a table.

Can RoCode fix it?

Yes. Paste the Output line into RoCode. It finds which side of the comparison is wrong in the script in your open place and adds the missing check or conversion.

Sources and further reading

How the code was checked: every block marked Fixed passes Luau's strict type checker against Roblox's API definitions (luau-lsp, 23 October 2026), and every block marked Breaks compiles and fails only when it runs. The message wording, including the swapped order for > and >=, was checked by running the broken code with the Luau command line tool and against the message strings in Roblox Studio itself on 23 October 2026. A type check catches misspelt APIs and wrong types, not game logic, so playtest in Studio before you publish.

Stop hunting errors line by line.

RoCode reads the scripts in your open place, fixes the error where it happens and tells you what it changed. Free every day, no card required.