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

Ottenendo 'bad argument #1 to X (number expected, got nil)' in FiveM? Come leggere il numero di argomento e riparare nil entities, pairs(nil), tonumber e errori di tabella.

Da qualche parte nella tua console, uno script si ferma con questo:

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

Una funzione è stata chiamata con un argomento che non può usare, e l'argomento è quasi sempre nil. Il messaggio ti dice quale funzione, quale argomento e quale tipo voleva. Questa guida mostra come leggerlo e le solite fonti di nil.

Come leggere il messaggio

text
bad argument #1 to 'X' (number expected, got nil)
  • X è il nome della funzione che ha protestato.
  • #1 è la posizione dell'argomento: #1 è il primo, #2 il secondo.
  • number expected è il tipo che la funzione ha bisogno. Può anche dire string, table o boolean.
  • got nil è quello che ha effettivamente ricevuto. Può anche essere got table, got string o got no value.

Apri la riga dall'errore e guarda la funzione denominata nel messaggio. Quindi guarda l'argomento in quella posizione e chiediti da dove viene.

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

Qui Config.Prices[item] è nil, perché item non è una chiave della tabella. L'errore è sulla riga math.floor, ma l'errore è nei dati.

table expected, got nil

Lo stesso messaggio con una tabella appare con funzioni table:

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

Crea la tabella prima di usarla:

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

Per una tabella che vive in una struttura condivisa, creala quando manca:

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

Looping su nil: pairs e ipairs

In Lua 5.3 e 5.4, che FiveM usa, il looping su nil fallisce con un messaggio che chiama il loop invece di pairs:

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

Controlla dove la tabella è definita: un errore di digitazione nel nome, il file di config non caricato dal manifest, o dati che non sono arrivati ancora. Una breve protezione evita l'arresto anomalo mentre trovi la vera causa:

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

Usalo come rete di sicurezza, non come correzione. Se Config.Jobs dovrebbe esistere, un loop vuoto nasconde solo il bug. Il messaggio correlato table index is nil copre le chiavi mancanti nelle tabelle di config annidate.

Nativi che ricevono nil

Molti nativi hanno bisogno di un numero, come un handle di entità. Un handle che è nil o 0 di solito significa che l'entità non esiste (ancora).

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

Fonti comuni:

  • L'entità non è caricata. Un veicolo generato dal server non è disponibile per il tuo client per un momento. Sul client, aspetta che esista:
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
  • Una funzione non ha restituito nulla. GetPlayerPed(-1), GetClosestVehicle e simili possono restituire 0 quando niente corrisponde. Controlla il valore prima di usarlo.
  • Un vettore sbagliato. Un nativo che vuole tre numeri, x, y, z, non accetta un'intera tabella. Passa coords.x, coords.y, coords.z, o usa un vector3 dove il nativo ne prende uno.
  • Una chiave mancante nel config. Config.Spawn.x è nil quando Config.Spawn è scritto con [1], [2], [3].

Il testo esatto dipende dal nativo, e alcuni nativi non sollevano un errore affatto ma non fanno nulla. Ecco perché una protezione vale la pena di aggiungere:

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

tostring, tonumber e string.format

Le funzioni di conversione sono un'altra fonte di nil:

  • tonumber('abc') restituisce nil, non un errore, quindi l'arresto anomalo viene più tardi quando usi il risultato.
  • tostring(value) restituisce sempre una stringa, anche per nil (dà 'nil'), quindi è sicuro da usare quando costruisci un testo.
  • string.format('%d', value) fallisce quando value è nil: bad argument #2 to 'format' (number expected, got nil).

Quando un numero viene da un giocatore o da un comando, controllalo:

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)

Nota che args[1] è nil quando il giocatore ha digitato /pay da solo, e tonumber(nil) restituisce nil, quindi il controllo sopra copre entrambi i casi.

Trova il nil

Quando la fonte non è ovvia, stampa i valori proprio prima della riga che fallisce:

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

Quindi traccia il nil di nuovo a dove dovrebbe essere stato impostato. Rimuovi le stampe quando hai finito.

Elenco di controllo

Sintomo Correzione
bad argument #1 to 'floor' (number expected, got nil) Il valore è mancante: controlla la chiave o la variabile che lo alimenta
bad argument #1 to 'insert' (table expected, got nil) Crea la tabella per prima: t = t or {}
bad argument #1 to 'for iterator' (table expected, got nil) La tabella che fai un loop è nil; controlla il suo nome e dove è riempita
Un nativo fallisce su un'entità Controlla DoesEntityExist(entity) e aspetta che l'entità si carichi
tonumber(...) dà nil Valida l'input del giocatore prima di usarlo
bad argument #2 to 'format' %d e %s hanno bisogno di un valore reale; controlla l'argomento in quella posizione

Se l'errore riguarda qualcosa di nil invece di un argomento errato, leggi attempt to compare nil e attempt to call a nil value.

Risposte rapide

Cosa significa 'bad argument #1 to X (number expected, got nil)'?

Una funzione ha ricevuto nil come primo argomento dove ha bisogno di un numero. X è la funzione, #1 è la posizione dell'argomento, e nil è quello che il tuo codice ha passato.

Come risolvo 'bad argument #1 to for iterator (table expected, got nil)'?

Hai eseguito un loop su una variabile che è nil con pairs o ipairs. Trova dove quella variabile è riempita e controlla che esista, o fai un loop su variable or {}.

Può un nativo ricevere nil senza un errore?

A seconda del nativo, un valore nil o non valido può essere trattato come 0 o semplicemente non fare nulla, quindi il bug può nascondersi. Controlla un'entità con DoesEntityExist(entity) prima di usarla.

Script senza questo problema

Advanced BoostingBoosting di veicoli dal tablet: contratti dalla classe D alla S+, crew e coda in tempo reale.Vedi script →CCTV Security CamerasTelecamere posizionabili, un tablet multi-vista in diretta e foto stampate come prove.Vedi script →Item Creator V2Crea oggetti utilizzabili con animazioni, props, effetti e altro — senza scrivere codice.Vedi script →

Continua a leggere