THE ORB
Starting the studio

attempt to index a nil value

A script expected some information to be ready and it was not there yet, so it stopped.

groupsThat feature stops workingcodeNeeds a developer

Do this first

Note which script and file the message names, then check whether it started before your framework did.

bug_reportPaste your whole console instead

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. 1

    The framework object has not loaded yet (most common on the client)

    A client file reads ESX, QBCore or PlayerData at 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. 2

    A config key that does not exist

    Config.Something.value where Config.Something was never defined, was renamed, or lives in a file that is not listed in fxmanifest.

  3. 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. 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. 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 Fixer

Errors that travel with this one