tentative de comparer un nombre avec nil / opération arithmétique sur une valeur nil : correction
Corrigez « attempt to compare number with nil » et « arithmetic on a nil value » dans FiveM : données de joueur non chargées, valeurs de config manquantes, tonumber et defaults sûrs avec `or`.
Sortie de la console :
SCRIPT ERROR: @my_script/server/main.lua:58: attempt to compare number with nil
SCRIPT ERROR: @my_script/client/main.lua:91: attempt to perform arithmetic on a nil value (field 'money')Une ligne du script utilise une valeur qui n'existe pas encore dans une comparaison ou un calcul. Voici ce qui laisse généralement la valeur vide, et comment rendre le script sûr.
Ce que l'erreur signifie
Lua vous donne nil pour toute variable ou entrée de table qui n'a pas de valeur. Comparer (<, >, <=) ou calculer (+, -, *, /) avec nil arrête le script avec un de ces messages :
attempt to compare number with nil(ouattempt to compare nil with number) : un côté de la comparaison estnil.attempt to perform arithmetic on a nil value: un calcul utilise une variablenil. Quand Lua connaît le nom, il l'ajoute, comme(field 'money')ou(local 'price').
Le numéro de ligne dans le message est la ligne avec la comparaison ou la somme. Le nil est l'une des valeurs de cette ligne. Imprimez-les pour voir lequel :
print('price', price, type(price))
print('count', count, type(count))
if price > count then
-- ...
end1. Les données du joueur ne sont pas encore chargées
La cause la plus courante : le script lit le joueur avant que le framework ait fini de le charger, par exemple dans les premières lignes d'un fichier, ou dans un thread qui démarre immédiatement.
-- runs too early on the client: money is nil
local money = ESX.GetPlayerData().money
if money > 100 then
-- ...
endAttendez l'événement chargé du framework, et lisez les données de là :
-- ESX client
local PlayerData = {}
RegisterNetEvent('esx:playerLoaded', function(xPlayer)
PlayerData = xPlayer
end)-- QBCore client
local QBCore = exports['qb-core']:GetCoreObject()
local PlayerData = {}
RegisterNetEvent('QBCore:Client:OnPlayerLoaded', function()
PlayerData = QBCore.Functions.GetPlayerData()
end)Sur le serveur, un objet joueur peut aussi être nil quand l'id est faux ou que le joueur a quitté. Vérifiez-le avant de l'utiliser :
local xPlayer = ESX.GetPlayerFromId(source)
if not xPlayer then return endlocal Player = QBCore.Functions.GetPlayer(source)
if not Player then return endSur QBox, l'équivalent est exports.qbx_core:GetPlayer(source), avec la même vérification nil.
Conseil : si le script redémarre pendant que vous êtes sur le serveur,
playerLoadeda déjà été déclenché et ne se déclenchera pas à nouveau. Lisez les données une fois quand la resource démarre aussi.
2. Une valeur de config manque
Vous avez ajouté une ligne à config.lua que le script n'a pas, ou le script lit une clé que votre ancienne config ne contient pas. Après une mise à jour, un vieux config.lua est une cause très courante.
-- config.lua of the old version has no Config.Price
if playerMoney >= Config.Price then
-- ...
endComparez votre config avec celle livrée avec la nouvelle version, et ajoutez les clés manquantes. Dans votre propre code, donnez à chaque paramètre une valeur par défaut :
local price = Config.Price or 1003. La valeur est une chaîne, pas un nombre
Les valeurs d'une base de données, d'une boîte d'entrée dans un menu ou d'un message JSON arrivent souvent comme du texte. Comparer une chaîne avec un nombre donne une erreur différente (attempt to compare number with string), mais une conversion qui échoue vous donne nil, ce qui ramène cette erreur. tonumber convertit, et retourne nil quand il ne peut pas :
local amount = tonumber(data.amount)
if not amount then
return -- not a number: stop here
end4. Utilisez or pour une valeur par défaut
or retourne le côté droit quand le côté gauche est nil (ou false). C'est le moyen le plus court de rendre un calcul sûr :
local count = tonumber(data.count) or 0
local total = (item.price or 0) * countUtilisez-le où une valeur manquante peut vraiment signifier zéro, comme un bonus optionnel. Où une valeur manquante est un bug, par exemple un prix qui doit exister, arrêtez avec un message clair au lieu de le cacher :
local price = Config.Items[name] and Config.Items[name].price
if not price then
print(('no price set for %s'):format(name))
return
end5. Un résultat de base de données ou de callback est vide
Une query qui ne trouve pas de ligne donne nil ou une table vide. Lire une colonne de celle-ci échoue :
local row = MySQL.single.await('SELECT balance FROM bank WHERE owner = ?', { identifier })
if row.balance > 0 then -- row is nil when the player has no row
-- ...
endVérifiez d'abord la ligne :
local row = MySQL.single.await('SELECT balance FROM bank WHERE owner = ?', { identifier })
local balance = row and row.balance or 0Il en va de même pour les serveurs callbacks : la réponse peut être nil si le callback n'a pas été trouvé ou n'a rien retourné. Si votre script attend un callback, gérez ce cas. Connexe : attempt to call a nil value est l'erreur sœur quand une fonction, pas une valeur, manque.
6. Une faute de frappe dans un nom de champ
xPlayer.money et xPlayer.Money sont différents. Il en va de même pour price et Price. Le message d'erreur nomme souvent le champ : vérifiez son orthographe par rapport à la documentation du framework ou par rapport à la table que vous imprimez avec print(json.encode(data)).
Liste de contrôle
| Symptôme | Correction |
|---|---|
| Erreur juste après avoir rejoint | Attendez l'événement player loaded avant de lire les données du joueur |
xPlayer ou Player est nil sur le serveur |
Vérifiez if not xPlayer then return end et l'id source |
| Erreur après la mise à jour d'un script | Ajoutez les nouvelles clés du config.lua fourni au vôtre |
| La valeur provient d'un menu ou JSON | Convertissez avec tonumber(value) et vérifiez qu'elle n'est pas nil |
| Une valeur peut manquer exprès | Utilisez value or 0 comme valeur par défaut |
| La query de base de données ne retourne rien | Vérifiez que la ligne n'est pas nil avant de lire ses colonnes |
| Le champ est nil même s'il devrait exister | Vérifiez l'orthographe et les majuscules |
Réponses rapides
Que signifie « attempt to compare number with nil » ?
Une ligne compare un nombre avec quelque chose qui n'a pas de valeur, comme price > 100 quand price est nil. Trouvez quelle variable est nil et pourquoi elle n'a jamais été définie.
Comment donner une valeur par défaut à une variable en Lua ?
Utilisez or : local count = tonumber(value) or 0. Si la valeur est nil ou pas un nombre, count devient 0.
Pourquoi cela ne se produit-il que juste après que je rejoigne le serveur ?
Le script lit les données du joueur avant que le framework les ait chargées. Attendez l'événement du joueur chargé, ou vérifiez que l'objet du joueur n'est pas nil avant de le lire.
Des scripts sans ce problème
Shop CreatorCréez un magasin en moins d’une minute — propriétaires, employés, coffres et braquages inclus.Voir le script →
Pawn Shop AppUn marché de prêt sur gage entre joueurs, directement dans lb-phone.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 →