table index is nil / index a nil value (field): FiveM Lua fix

Ripara 'table index is nil' e 'attempt to index a nil value (field x)' in FiveM Lua: chiavi config mancanti, assegnamenti t[nil], tabelle annidate e modelli di accesso sicuro.

Due errori che si assomigliano vengono fuori tutto il tempo negli script FiveM:

text
SCRIPT ERROR: @my_script/server/main.lua:42: table index is nil
SCRIPT ERROR: @my_script/client/main.lua:19: attempt to index a nil value (field 'shops')

Significano cose diverse. Il primo riguarda una chiave nil, il secondo una tabella nil. Entrambi si riducono a un valore che il tuo codice si aspettava e non ha trovato. Questa guida mostra come distinguerli e come scrivere l'accesso in modo che non possa bloccarsi.

table index is nil

Hai assegnato a una tabella, e la chiave era nil:

lua
local cache = {}

local function remember(identifier, data)
    cache[identifier] = data     -- table index is nil when identifier is nil
end

Lua consente qualsiasi valore come chiave tranne nil (e NaN). Leggere cache[nil] dà solo nil, ma scrivere su di esso solleva l'errore.

Trova quale variabile tra le parentesi è nil su quella riga. Le solite fonti:

  • Una ricerca di giocatore che non ha restituito nulla. GetPlayerIdentifierByType(source, 'license') restituisce nil quando il giocatore non ha un identificatore di quel tipo, ad esempio quando il giocatore non è connesso attraverso la piattaforma che ti aspetti.
  • Un source sbagliato. Sul server, controlla che l'evento provenga davvero da un giocatore. Una chiamata dalla console non ha un giocatore dietro.
  • Un field mancante nei dati: data.id è nil perché il mittente ha usato data.Id.

Stampalo per essere sicuro:

lua
print('identifier', identifier, type(identifier))

Quindi ferma l'assegnazione quando la chiave manca, e decidi se è un errore o un caso normale:

lua
local function remember(identifier, data)
    if not identifier then
        return print('remember: no identifier, skipping')
    end
    cache[identifier] = data
end

attempt to index a nil value (field 'x')

text
attempt to index a nil value (field 'shops')

Qui la tabella è mancante. Il nome tra le parentesi è il field che era nil, e la cosa che l'hai indicizzato è sulla riga:

lua
local first = Config.shops[1]    -- Config.shops is nil, so [1] fails

Lua chiama quello che conosce. Poche forme che vedrai:

Messaggio Significato
(global 'Config') La variabile globale Config è nil
(local 'data') Una variabile locale è nil, spesso un argomento di funzione
(field 'shops') Config.shops è nil
(field '?') Una tabella trovata da una chiave variabile, come Config.Shops[id], è nil
(upvalue 'cache') Una variabile da uno scope esterno è nil

Per field '?', Lua non può nominarla perché è calcolato:

lua
Config.Shops[id].label          -- attempt to index a nil value (field '?')

La correzione è la stessa: trova quale passo della catena è nil. Stampa ogni passo:

lua
print(Config)
print(Config.Shops)
print(Config.Shops[id])

Tabelle di config annidate

La maggior parte di questi errori proviene dai file config:

lua
Config = {}
Config.Shops = {
    bar = { label = 'Bar', items = { 'beer', 'water' } },
}

-- somewhere else
local items = Config.Shops[shopName].items

Se shopName è 'Bar' invece di 'bar', Config.Shops[shopName] è nil e il prossimo .items si blocca. Cause da controllare:

  1. Ortografia o case diverse. Le chiavi Lua sono sensibili alle maiuscole.
  2. Il file config non è caricato. Deve essere in shared_scripts (o la lista del lato giusto) di fxmanifest.lua, prima del file che lo legge.
  3. Il config è definito solo su un lato. Un file elencato sotto server_scripts è invisibile al client.
  4. Una chiave numerica rispetto a una chiave stringa. Config.Shops[1] e Config.Shops['1'] sono voci diverse. Questo spesso accade dopo che i dati passano attraverso JSON, vedi FiveM json.decode errors.
lua
-- fxmanifest.lua
shared_scripts { 'config.lua' }
client_scripts { 'client/*.lua' }
server_scripts { 'server/*.lua' }

Modelli di accesso sicuro

Quando un valore mancante è un caso normale, scrivi l'accesso in modo che lo gestisca.

Controlla ogni passo con and:

lua
local shop = Config.Shops and Config.Shops[shopName]
if not shop then
    return print(('Unknown shop: %s'):format(tostring(shopName)))
end
print(shop.label)

Usa or per un default:

lua
local items = (shop and shop.items) or {}
local radius = Config.Radius or 5.0

Crea un piccolo helper quando leggi percorsi profondi spesso:

lua
local function get(t, ...)
    for _, key in ipairs({ ... }) do
        if type(t) ~= 'table' then return nil end
        t = t[key]
    end
    return t
end

local label = get(Config, 'Shops', shopName, 'label')

Attenzione: non nascondere ogni nil con or {}. Se una tabella che deve esistere è mancante, è un bug nel config o nell'ordine di caricamento, e un fallback silenzioso sposta solo l'errore da qualche parte meno ovvio. Usa protezioni per i valori che possono legittimamente essere assenti.

Scarica una tabella per vedere cosa contiene

Quando non sei sicuro di cosa contiene una tabella, stampalo come JSON:

lua
print(json.encode(Config.Shops, { indent = true }))

Vedrai le vere chiavi e notperai un errore di digitazione, un case diverso o un numero dove ti aspettavi una stringa. Fallo nel punto in cui l'errore accade, non all'inizio del file, perché i dati potrebbero essere riempiti in seguito.

Elenco di controllo

Sintomo Correzione
table index is nil La chiave in t[key] = value è nil; stampala e ritorna presto se è mancante
attempt to index a nil value (field 'shops') Il field denominato non è impostato nella tabella prima di esso; controlla il nome e l'ortografia
attempt to index a nil value (field '?') Una ricerca con una chiave variabile non ha trovato nulla; controlla la chiave e il suo case
Funziona sul server, nil sul client Il config non è in shared_scripts
File config ignorato Elencalo prima dei file che lo usano
Chiave numerica vs chiave stringa [1] e ['1'] differiscono; converti con tonumber o tostring

Per gli altri messaggi nil comuni, vedi attempt to compare nil e bad argument errors.

Risposte rapide

Cosa significa 'table index is nil'?

Lo script ha provato a scrivere in una tabella usando nil come chiave, come t[key] = value quando key è nil. Lua non consente nil come chiave, quindi si ferma.

Qual è la differenza tra 'table index is nil' e 'attempt to index a nil value'?

In 'table index is nil' la chiave è nil. In 'attempt to index a nil value' la tabella stessa è nil, quindi non c'è nulla da leggere o scrivere.

Perché l'errore dice field '?' invece di un nome?

Quando la chiave è una variabile come Config.Shops[id], Lua non può nominarla. Mostra ?. Guarda la riga e trova quale parte della catena è nil.

Script senza questo problema

Shop CreatorCrea un negozio in meno di un minuto — proprietari, dipendenti, casseforti e rapine inclusi.Vedi script →Quest CreatorUn editor visuale di missioni e dialoghi con gli NPC, costruito nodo per nodo in gioco.Vedi script →Item Creator V2Crea oggetti utilizzabili con animazioni, props, effetti e altro — senza scrivere codice.Vedi script →

Continua a leggere