Errore FiveM json.decode: correzioni per nil, stringa vuota e JSON non valido
json.decode non funziona o restituisce nil nel tuo script FiveM? Perché la decodifica di nil, JSON vuoto o modificato manualmente si interrompe, cosa fa json.encode alle chiavi miste e come usare pcall in modo sicuro.
L'errore appare una riga dopo la decodifica:
SCRIPT ERROR: @my_script/server/main.lua:31: attempt to index a nil value (local 'data')local data = json.decode(row.metadata)
print(data.level) -- data is niljson.decode ti ha dato nulla di utilizzabile, quindi la riga successiva ha indicizzato nil. La decodifica raramente è l'errore reale. L'input era nil, vuoto o rotto, oppure la tabella che avevi salvato in precedenza non era quello che pensavi. Ecco come trovare quale, e come decodificare in modo sicuro.
1. La stringa è nil o vuota
Il caso più comune. Il valore che decodifichi non esiste ancora:
- Una colonna di database che è
NULL. Una riga senza dati salvati restituiscenilper quella colonna. - Una query senza risultato.
MySQL.scalar.await(...)eMySQL.single.await(...)restituiscononilquando nessuna riga corrisponde. Vedi guida alle query oxmysql per quello che ogni funzione restituisce. - Una chiave KVP che non è mai stata impostata.
GetResourceKvpString('my_key')restituiscenilquando la chiave non esiste, vedi FiveM resource KVP. - Un file che manca.
LoadResourceFile(GetCurrentResourceName(), 'data.json')restituiscenilquando il file non è presente. - Una stringa vuota. Una colonna salvata come
''non è JSON valido nemmeno.
La decodifica di nil o '' è un bug nel chiamante, quindi controlla prima la stringa:
local raw = GetResourceKvpString('my_key')
local data = {}
if raw and raw ~= '' then
data = json.decode(raw) or {}
end2. Il JSON non è valido
Una stringa presente può comunque essere non valida. Cause tipiche quando un file o un valore di database è stato modificato a mano:
- Una virgola finale dopo l'ultima voce:
{ "a": 1, } - Virgolette singole invece di doppie:
{ 'a': 1 } - Commenti nel file. JSON non li consente.
- Una parentesi graffa o virgoletta mancante dopo aver copiato parte di un file.
- Sintassi Lua incollata in un file JSON, come
a = 1o[1] = 'x'. - Un carattere rotto da un editor di testo, come virgolette ricurve copiate da una pagina web.
{
"items": [
{ "name": "water", "count": 2 },
{ "name": "bread", "count": 1 }
]
}Valida il file prima di incolpare lo script. VS Code sottolinea gli errori JSON mentre digiti, e un validatore JSON online mostra la posizione esatta dell'errore.
3. Decodifica sempre con pcall
A seconda dell'input e della build, una stringa non valida genera un errore Lua o torna come nil. Non hai bisogno di ricordare quale: avvolgi la chiamata in modo che entrambi i casi siano gestiti.
local function safeDecode(str)
if type(str) ~= 'string' or str == '' then
return nil
end
local ok, result = pcall(json.decode, str)
if not ok or type(result) ~= 'table' then
return nil
end
return result
end
local data = safeDecode(row.metadata) or {}
print(data.level)Il controllo type(result) ~= 'table' cattura anche un valore che è JSON valido ma non un oggetto, come "hello" o 5.
Suggerimento: quando una decodifica non riesce e non sai perché, stampa la stringa grezza accanto al suo tipo:
print(type(str), str). Unnilo una riga vuota mostra la causa subito.
4. json.encode e le chiavi che cambiano
Una decodifica può funzionare e comunque darti dati errati, perché la tabella è stata salvata in una forma che non sopravvive al roundtrip. JSON ha due forme: una lista [...] e un oggetto {...} con chiavi testo.
local saved = json.encode({ [100] = 'a', [250] = 'b' })
local loaded = json.decode(saved)
print(loaded[100]) -- nil
print(loaded['100']) -- 'a'Cosa significa in pratica:
- Le chiavi numeriche diventano chiavi di testo quando la tabella viene salvata come oggetto. Dopo la decodifica, cerca il valore con la chiave di testo, o converti la chiave con
tonumber. - Array sparsi con buchi (
{ [1] = 'a', [3] = 'c' }) non sono una lista pulita, quindi possono essere scritti come oggetto invece che come array. - Tabelle miste, con sia elementi lista che chiavi nominate, non si mappano pulitamente a nessuna forma. Mantieni una lista come una lista, e metti i campi nominati in una tabella separata.
- Funzioni, userdata e vettori non possono essere scritti come dati JSON semplici. Converti un vettore a
{ x = v.x, y = v.y, z = v.z }prima di codificarlo. - Una tabella vuota è solitamente scritta come
[], quindi rileggila come una lista o una tabella vuota, non come un oggetto.
Un modo sicuro per memorizzare le coordinate:
-- save
local payload = json.encode({ x = coords.x, y = coords.y, z = coords.z })
-- load
local pos = safeDecode(payload)
if pos then
SetEntityCoords(ped, pos.x, pos.y, pos.z, false, false, false, false)
endUsa json.encode(value, { indent = true }) durante il debug, poiché è molto più facile da leggere.
5. Decodifica una volta e controlla il tipo
I dati da un database possono raggiungere il tuo script come stringa in un posto e come tabella in un altro. Alcune librerie e framework decodificano le colonne JSON per te, altre restituiscono il testo grezzo. Prima di decodificare, controlla quello che hai:
local meta = row.metadata
if type(meta) == 'string' then
meta = safeDecode(meta)
end
meta = meta or {}Decodificare qualcosa che è già una tabella è un bug, e un controllo di tipo non costa nulla.
Elenco di controllo
| Sintomo | Soluzione |
|---|---|
attempt to index a nil value (local 'data') dopo la decodifica |
La stringa era nil o non valida; controlla prima della decodifica e usa pcall |
| Decodifica di una colonna di database | I risultati NULL e senza righe sono nil; proteggi con if raw and raw ~= '' |
| Una lettura KVP non dà nulla | La chiave non è mai stata impostata; usa una tabella predefinita |
| Un file modificato manualmente non riesce | Rimuovi virgole finali, commenti e virgolette singole; convalidalo in un editor |
| Chiavi numeriche perse dopo la decodifica | Le chiavi JSON sono testo; leggi t['100'] o converti con tonumber |
| Vettori scritti come JSON | Salva x, y e z come campi separati |
Risposte rapide
Perché json.decode restituisce nil o genera un errore?
La stringa è nil, vuota o non è JSON valido. A seconda del caso, genera un errore o non restituisce nulla, quindi avvolgi la chiamata in pcall e controlla il risultato.
Perché le mie chiavi numeriche diventano stringhe dopo json.decode?
Le chiavi dell'oggetto JSON sono sempre testo. Una tabella come { [100] = true } viene salvata come oggetto con la chiave di testo 100 e torna con la chiave '100', quindi data[100] è nil.
Come verifico che un file JSON sia valido?
Aprilo in VS Code, che evidenzia gli errori JSON nell'editor, oppure incollalo in un validatore JSON online. Gli errori usuali sono una virgola finale, virgolette singole o un commento.
Script senza questo problema
Item Creator V2Crea oggetti utilizzabili con animazioni, props, effetti e altro — senza scrivere codice.Vedi script →
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 →