attempt to index a nil value
A script expected some information to be ready and it was not there yet, so it stopped.
Do this first
Note which script and file the message names, then check whether it started before your framework did.
What it means
Something used the . or [] operator on a variable that is nil. In Lua, a.b is only legal when a is a table; when a is nil the script stops on that line. The message usually names what was nil: (field 'PlayerData'), (global 'ESX'), (local 'data'), (upvalue 'Config').
That name in parentheses is the most useful part of the message, and each kind points somewhere different:
• global 'X' — never assigned, or assigned in a file that did not run.
• field 'X' — the table exists but has no such key.
• local 'X' / upvalue 'X' — assigned in this file, but not before this line ran.
What causes it
Ordered by how often it is the answer.
- 1
The framework object has not loaded yet (most common on the client)
A client file reads
ESX,QBCoreorPlayerDataat file scope or in an early thread, before the framework has handed the player object over. Your resource starts before the framework finishes loading the player. - 2
A config key that does not exist
Config.Something.valuewhereConfig.Somethingwas never defined, was renamed, or lives in a file that is not listed in fxmanifest. - 3
The server sent nil
A client event handler indexes a table the server passed, and on some path the server passed nothing.
TriggerClientEvent('x', src)with no payload gives the handler nil. - 4
A wrapper returned nothing
Natives do not return tables, but a helper around one can return nil for an invalid entity, and the caller indexes that.
- 5
Load order
The file that defines the table is listed AFTER the file that uses it in fxmanifest, so at the moment of use it does not exist yet.
How to tell which one is yours
Print the container, not the field, directly above the failing line:
print(json.encode(Config.Something))
If it prints null, the container is the problem and the field is a red herring. If the parenthesised name is a framework global, add a wait and see if the error moves: a timing problem goes away, a missing key does not.
Where to look
Open the file and line from the stack. Read the whole statement, not just the part before the dot: in a.b.c.d any of a, a.b or a.b.c could be the nil one, and the parenthesised name tells you which.
How to fix it
For framework timing, never read the object at file scope:
local PlayerData = {}
RegisterNetEvent('esx:playerLoaded', function(xPlayer)
PlayerData = xPlayer
end)
-- when you genuinely need it during startup:
CreateThread(function()
while not ESX or not ESX.IsPlayerLoaded() do Wait(100) end
-- safe from here
end)For everything else, guard before indexing:
local entry = Config.Jobs[job] if not entry then return end
Still stuck on your own code?
This page is what this error usually means. Paste your console into Server Fixer and it will rank everything in it and tell you what to do first, and if you would rather not touch it, ORBIE can repair the script and hand the resource back ready to drop in.
bug_reportOpen Server FixerErrors that travel with this one
- attempt to call a nil value
- PlayerData is empty or not loaded yet
- The framework object is nil (ESX / QBCore)
- cannot resume dead coroutine
- SCRIPT ERROR in citizen:/scripting/lua/scheduler.lua
- attempt to index a number, boolean or string value
- attempt to yield across a C-call boundary
- stack overflow
- table index is nil