bad argument #1 to 'X' (number expected, got nil): FiveM Lua fix

Getting 'bad argument #1 to X (number expected, got nil)' in FiveM? How to read the argument number and fix nil entities, pairs(nil), tonumber and table errors.

Somewhere in your console, a script stops with this:

text
SCRIPT ERROR: @my_script/client/main.lua:57: bad argument #1 to 'floor' (number expected, got nil)

A function was called with an argument it cannot use, and the argument is almost always nil. The message tells you which function, which argument and what type it wanted. This guide shows how to read it and the usual sources of the nil.

How to read the message

text
bad argument #1 to 'X' (number expected, got nil)
  • X is the name of the function that complained.
  • #1 is the position of the argument: #1 is the first one, #2 the second.
  • number expected is the type the function needs. It can also say string, table or boolean.
  • got nil is what it actually received. It can also be got table, got string or got no value.

Open the line from the error and look at the function named in the message. Then look at the argument in that position and ask where it comes from.

lua
local price = Config.Prices[item]
local rounded = math.floor(price)   -- bad argument #1 to 'floor' (number expected, got nil)

Here Config.Prices[item] is nil, because item is not a key of the table. The error is on the math.floor line, but the mistake is in the data.

table expected, got nil

The same message with a table appears with table functions:

text
bad argument #1 to 'insert' (table expected, got nil)
lua
local list
table.insert(list, 'a')     -- list was never created

Create the table before you use it:

lua
local list = {}
table.insert(list, 'a')

For a table that lives in a shared structure, create it when it is missing:

lua
players[source] = players[source] or {}
table.insert(players[source], item)

Looping over nil: pairs and ipairs

In Lua 5.3 and 5.4, which FiveM uses, looping over nil fails with a message that names the loop instead of pairs:

text
bad argument #1 to 'for iterator' (table expected, got nil)
lua
for _, job in pairs(Config.Jobs) do   -- Config.Jobs is nil

Check where the table is defined: a typo in the name, the config file not loaded by the manifest, or data that did not arrive yet. A short guard avoids the crash while you find the real cause:

lua
for _, job in pairs(Config.Jobs or {}) do

Use it as a safety net, not as a fix. If Config.Jobs should exist, an empty loop only hides the bug. The related message table index is nil covers missing keys in nested config tables.

Natives that receive nil

Many natives need a number, such as an entity handle. A handle that is nil or 0 usually means the entity does not exist (yet).

lua
local vehicle = GetVehiclePedIsIn(ped, false)
local plate = GetVehicleNumberPlateText(vehicle)   -- vehicle is 0 when the ped is on foot

Common sources:

  • The entity is not loaded. A vehicle spawned by the server is not available to your client for a moment. On the client, wait until it exists:
lua
local vehicle = NetToVeh(netId)
local timeout = 0
while not DoesEntityExist(vehicle) and timeout < 100 do
    Wait(50)
    vehicle = NetToVeh(netId)
    timeout = timeout + 1
end
  • A function returned nothing. GetPlayerPed(-1), GetClosestVehicle and similar can return 0 when nothing matches. Check the value before you use it.
  • A wrong vector. A native that wants three numbers, x, y, z, does not accept a whole table. Pass coords.x, coords.y, coords.z, or use a vector3 where the native takes one.
  • A missing key in the config. Config.Spawn.x is nil when Config.Spawn is written with [1], [2], [3].

The exact text depends on the native, and some natives do not raise an error at all but do nothing. That is why a guard is worth adding:

lua
if vehicle ~= 0 and DoesEntityExist(vehicle) then
    SetVehicleEngineOn(vehicle, true, true, false)
end

tostring, tonumber and string.format

Conversion functions are another source of nil:

  • tonumber('abc') returns nil, not an error, so the crash comes later when you use the result.
  • tostring(value) always returns a string, even for nil (it gives 'nil'), so it is safe to use when you build a text.
  • string.format('%d', value) fails when value is nil: bad argument #2 to 'format' (number expected, got nil).

When a number comes from a player or from a command, check it:

lua
RegisterCommand('pay', function(source, args)
    local amount = tonumber(args[1])
    if not amount then
        return print('Usage: /pay [amount]')
    end
    print(('Paying %d'):format(amount))
end)

Note args[1] is nil when the player typed /pay alone, and tonumber(nil) returns nil, so the check above covers both cases.

Find the nil

When the source is not obvious, print the values just before the failing line:

lua
print('item', item, type(item))
print('price', Config.Prices[item], type(Config.Prices[item]))

Then trace the nil back to where it should have been set. Remove the prints when you are done.

Checklist

Symptom Fix
bad argument #1 to 'floor' (number expected, got nil) The value is missing: check the key or variable that feeds it
bad argument #1 to 'insert' (table expected, got nil) Create the table first: t = t or {}
bad argument #1 to 'for iterator' (table expected, got nil) The table you loop over is nil; check its name and where it is filled
A native fails on an entity Check DoesEntityExist(entity) and wait for the entity to load
tonumber(...) gives nil Validate player input before you use it
bad argument #2 to 'format' %d and %s need a real value; check the argument in that position

If the error is about something being nil instead of a bad argument, read attempt to compare nil and attempt to call a nil value.

Quick answers

What does 'bad argument #1 to X (number expected, got nil)' mean?

A function received nil as its first argument where it needs a number. X is the function, #1 is the position of the argument, and nil is what your code passed.

How do I fix 'bad argument #1 to for iterator (table expected, got nil)'?

You looped over a variable that is nil with pairs or ipairs. Find where that variable is filled and check it exists, or loop over variable or {}.

Can a native receive nil without an error?

Depending on the native, a nil or invalid value may be treated as 0 or simply do nothing, so the bug can hide. Check an entity with DoesEntityExist(entity) before you use it.

Scripts that skip this problem

Advanced BoostingTablet-driven vehicle boosting: contracts from class D to S+, crews and a live queue.View script →CCTV Security CamerasPlaceable cameras, a live multi-view tablet and printed evidence photos.View script →Item Creator V2Create usable items with animations, props, effects and more — without writing code.View script →

Keep reading