Erreur FiveM json.decode : corrections pour nil, chaîne vide et JSON invalide
json.decode échoue ou retourne nil dans votre script FiveM ? Pourquoi décoder nil, JSON vide ou édité à la main casse, ce que json.encode fait aux clés mixtes, et comment utiliser pcall en toute sécurité.
L'erreur apparaît une ligne après le décodage :
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 ne vous a donné rien d'utilisable, donc la ligne suivante a indexé nil. Le décodage est rarement la véritable faute. L'entrée était nil, vide ou cassée, ou la table que vous aviez sauvegardée n'était pas ce que vous pensiez. Voici comment découvrir lequel, et comment décoder en toute sécurité.
1. La chaîne est nil ou vide
Le cas le plus courant. La valeur que vous décodez n'existe pas encore :
- Une colonne de base de données qui est
NULL. Une ligne sans données sauvegardées retournenilpour cette colonne. - Une requête sans résultat.
MySQL.scalar.await(...)etMySQL.single.await(...)retournentnilquand aucune ligne ne correspond. Consultez le guide des requêtes oxmysql pour voir ce que chaque fonction retourne. - Une clé KVP qui n'a jamais été définie.
GetResourceKvpString('my_key')retournenilquand la clé n'existe pas, consultez FiveM resource KVP. - Un fichier qui manque.
LoadResourceFile(GetCurrentResourceName(), 'data.json')retournenilquand le fichier n'est pas là. - Une chaîne vide. Une colonne sauvegardée comme
''n'est pas du JSON valide non plus.
Décoder nil ou '' est un bogue chez l'appelant, donc vérifiez la chaîne d'abord :
local raw = GetResourceKvpString('my_key')
local data = {}
if raw and raw ~= '' then
data = json.decode(raw) or {}
end2. Le JSON est invalide
Une chaîne qui est présente peut toujours être invalide. Causes typiques quand un fichier ou une valeur de base de données a été édité à la main :
- Une virgule de fin après la dernière entrée :
{ "a": 1, } - Guillemets simples à la place des guillemets doubles :
{ 'a': 1 } - Commentaires dans le fichier. JSON ne les permet pas.
- Un crochet ou guillemet manquant après la copie d'une partie d'un fichier.
- Syntaxe Lua collée dans un fichier JSON, comme
a = 1ou[1] = 'x'. - Un caractère cassé d'un éditeur de texte, comme les guillemets courbes copiés d'une page web.
{
"items": [
{ "name": "water", "count": 2 },
{ "name": "bread", "count": 1 }
]
}Validez le fichier avant de blâmer le script. VS Code souligne les erreurs JSON au fur et à mesure que vous tapez, et un validateur JSON en ligne montre la position exacte de la faute.
3. Toujours décoder avec pcall
Selon l'entrée et la version, une mauvaise chaîne lève une erreur Lua ou revient comme nil. Vous n'avez pas besoin de vous souvenir lequel : enveloppez l'appel pour que les deux soient gérés.
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)La vérification type(result) ~= 'table' attrape aussi une valeur qui est du JSON valide mais pas un objet, comme "hello" ou 5.
Conseil : quand un décodage échoue et vous ne savez pas pourquoi, imprimez la chaîne brute à côté de son type :
print(type(str), str). Unnilou une ligne vide montre la cause immédiatement.
4. json.encode et les clés qui changent
Un décodage peut fonctionner et vous donner quand même les mauvaises données, parce que la table a été sauvegardée dans une forme qui ne survit pas au aller-retour. JSON a deux formes : une liste [...] et un objet {...} avec des clés texte.
local saved = json.encode({ [100] = 'a', [250] = 'b' })
local loaded = json.decode(saved)
print(loaded[100]) -- nil
print(loaded['100']) -- 'a'Ce que cela signifie en pratique :
- Les clés numériques deviennent des clés texte quand la table est sauvegardée comme un objet. Après décodage, cherchez la valeur avec la clé texte, ou convertissez la clé avec
tonumber. - Les tableaux clairsemés avec des trous (
{ [1] = 'a', [3] = 'c' }) ne sont pas une liste propre, donc ils peuvent être écrits comme un objet à la place d'un tableau. - Les tables mixtes, avec à la fois des éléments de liste et des clés nommées, ne se mappent pas proprement à aucune forme. Gardez une liste comme une liste, et mettez les champs nommés dans une table séparée.
- Les fonctions, userdata et vecteurs ne peuvent pas être écrits comme des données JSON simples. Convertissez un vecteur en
{ x = v.x, y = v.y, z = v.z }avant de l'encoder. - Une table vide est généralement écrite comme
[], donc relisez-la comme une liste ou une table vide, pas comme un objet.
Un moyen sûr de stocker les coordonnées :
-- 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)
endUtilisez json.encode(value, { indent = true }) pendant le débogage, car c'est beaucoup plus facile à lire.
5. Décoder une fois, et vérifier le type
Les données d'une base de données peuvent atteindre votre script comme une chaîne à un endroit et comme une table à un autre. Certaines bibliothèques et frameworks décodent les colonnes JSON pour vous, d'autres retournent le texte brut. Avant de décoder, vérifiez ce que vous tenez :
local meta = row.metadata
if type(meta) == 'string' then
meta = safeDecode(meta)
end
meta = meta or {}Décoder quelque chose qui est déjà une table est un bogue, et une vérification de type ne coûte rien.
Liste de contrôle
| Symptôme | Solution |
|---|---|
attempt to index a nil value (local 'data') après décodage |
La chaîne était nil ou invalide ; vérifiez-la avant de décoder et utilisez pcall |
| Décodage d'une colonne de base de données | NULL et les résultats sans ligne sont nil ; protégez avec if raw and raw ~= '' |
| Une lecture KVP ne donne rien | La clé n'a jamais été définie ; utilisez une table par défaut |
| Un fichier édité à la main échoue | Supprimez les virgules de fin, les commentaires et les guillemets simples ; validez-le dans un éditeur |
| Clés numériques perdues après décodage | Les clés JSON sont du texte ; lisez t['100'] ou convertissez avec tonumber |
| Vecteurs écrits comme JSON | Enregistrez x, y et z comme champs séparés |
Réponses rapides
Pourquoi json.decode retourne-t-il nil ou lève-t-il une erreur ?
La chaîne est nil, vide ou n'est pas du JSON valide. Selon le cas, il lève une erreur ou ne retourne rien, donc enveloppez l'appel dans pcall et vérifiez le résultat.
Pourquoi mes clés numériques sont-elles des chaînes après json.decode ?
Les clés d'objet JSON sont toujours du texte. Une table comme { [100] = true } est sauvegardée comme un objet avec la clé texte 100 et revient avec la clé '100', donc data[100] est nil.
Comment vérifier qu'un fichier JSON est valide ?
Ouvrez-le dans VS Code, qui marque les erreurs JSON dans l'éditeur, ou collez-le dans un validateur JSON en ligne. Les fautes habituelles sont une virgule de fin, des guillemets simples ou un commentaire.
Des scripts sans ce problème
Item Creator V2Créez des items utilisables avec animations, props, effets et plus — sans écrire une ligne de code.Voir le script →
Shop CreatorCréez un magasin en moins d’une minute — propriétaires, employés, coffres et braquages inclus.Voir le script →
Quest CreatorUn éditeur visuel de quêtes et de dialogues PNJ, construit nœud par nœud en jeu.Voir le script →