tentative d'appel d'une valeur nil (field, global, method) : comment le corriger
Vous recevez « attempt to call a nil value » dans FiveM ? Ce que signifient les variantes field, global et method, et comment corriger une faute de frappe, un export manquant ou une erreur deux-points-contre-point.
Dans la console :
SCRIPT ERROR: @my_script/server/main.lua:42: attempt to call a nil value (field 'GetPlayerFromId')
SCRIPT ERROR: @my_script/client/main.lua:17: attempt to call a nil value (global 'DrawText3D')
SCRIPT ERROR: @my_script/client/main.lua:63: attempt to call a nil value (method 'Notify')Lua vous dit qu'une ligne a essayé d'exécuter une fonction qui n'existe pas. Cet article explique les trois variantes, les causes habituelles, et comment corriger chacune.
Ce que l'erreur signifie
En Lua, un nom manquant n'est pas une erreur en soi : le lire donne nil. L'erreur n'apparaît que quand vous mettez des crochets après, car vous ne pouvez pas exécuter nil. Le texte entre crochets vous dit comment le script a atteint la fonction manquante :
attempt to call a nil value (global 'X'): un appel nu commeX(). La fonction n'est définie nulle part que le script puisse voir.attempt to call a nil value (field 'X'): un appel via une table commeESX.X()ouQBCore.Functions.X(). La table existe, mais elle n'a pas d'entrée nomméeX.attempt to call a nil value (method 'X'): un appel avec deux-points commeobj:X(). L'objet existe, mais n'a pas de méthodeX.
Le fichier et la ligne devant le message (@my_script/server/main.lua:42) est la ligne qui fait l'appel. Si vous n'êtes pas sûr de comment lire le reste de la sortie, voir comment lire une erreur de script FiveM.
1. Une faute de frappe dans le nom
Lua est sensible à la casse. GetPlayerFromId et getPlayerFromId sont deux noms différents, et il en va de même pour TriggerClientEvent et TriggerclientEvent. Comparez le nom dans l'erreur avec la documentation du framework, lettre par lettre.
2. La fonction n'existe pas dans votre version
Les frameworks renomment et suppriment les fonctions. C'est la cause la plus courante sur les scripts écrits pour une autre version de votre framework.
-- an old call that may be gone on your version
local xPlayer = ESX.GetPlayerFromId(source)
xPlayer.getInventoryItem('bread')Vérifiez ce que votre framework offre vraiment. Imprimez la table pour voir ses entrées :
for name, value in pairs(ESX) do
print(name, type(value))
endSi la fonction dont vous avez besoin n'est pas dans la liste, le script et le framework ne correspondent pas. Mettez à jour le framework, mettez à jour le script, ou remplacez l'appel par celui que votre version a.
3. L'export manque
Les exports sont des fonctions qu'une autre resource fournit. Quand la resource est arrêtée, n'a pas démarré, ou n'exporte pas ce nom, l'appel échoue.
local core = exports['qb-core']:GetCoreObject()
core.Functions.GetPlayer(source)Si la resource ne fonctionne pas, FiveM imprime No such export à la place. Si elle fonctionne mais que le nom de l'export est faux, vous pouvez vous retrouver avec un nil field. Démarrez d'abord la resource dans server.cfg, et vérifiez les noms exacts des exports dans sa documentation ou fxmanifest.lua. Deux correctifs connexes : ESX est nil et No such export getSharedObject.
4. Deux-points contre point
Un deux-points passe l'objet comme un premier argument caché. Un point ne le fait pas. Les mélanger donne soit cette erreur, soit les mauvais arguments.
-- calls the method with the object as first argument
player:Notify('hello')
-- calls a plain function stored in a table
Utils.Notify('hello')Si l'erreur dit (method 'Notify'), l'objet n'a pas d'entrée Notify : utilisez la forme de point si la fonction vit sur la table de la bibliothèque, ou vérifiez que l'objet est vraiment ce que vous pensez. Avec ox_lib, par exemple, lib.notify({...}) est un appel de point sur la table lib.
5. La fonction est définie plus tard ou dans un autre fichier
Une fonction locale doit être définie avant la ligne qui l'appelle, dans le même fichier. Une fonction définie dans un autre fichier n'est visible que si elle est globale, et seulement si ce fichier est chargé par le même côté (client ou serveur) de la même resource.
-- fails: DoThing is defined below the call
DoThing()
local function DoThing()
print('hi')
endDéplacez la définition au-dessus de l'appel, ou déclarez-la d'abord avec local DoThing et assignez-la plus tard. Vérifiez aussi fxmanifest.lua : un fichier qui n'est pas listé dans client_scripts, server_scripts ou shared_scripts ne charge jamais, donc ses fonctions n'existent jamais.
client_scripts { 'client/*.lua' }
server_scripts { 'server/*.lua' }
shared_scripts { '@ox_lib/init.lua', 'config.lua' }6. Une fonction client utilisée sur le serveur, ou l'inverse
De nombreux natives et fonctions de framework n'existent que d'un seul côté. PlayerPedId est client uniquement, et GetPlayerIdentifiers est serveur uniquement. Les tables du framework diffèrent aussi : ESX.GetPlayerFromId est une fonction serveur, tandis que le client utilise ESX.GetPlayerData. Un script qui s'exécute dans shared_scripts s'exécute des deux côtés, donc un appel qui fonctionne d'un côté se bloque de l'autre.
Conseil : le test le plus rapide est une impression juste avant la ligne défaillante :
print(type(ESX.GetPlayerFromId)). S'il imprimenil, la fonction manque. S'il imprimefunction, le vrai problème est ailleurs.
Gardez-le en place pendant que vous déboguez
Vérifiez avant d'appeler, pour obtenir un message clair au lieu d'un crash :
local fn = ESX.GetPlayerFromId
if type(fn) ~= 'function' then
print('GetPlayerFromId is missing: check the ESX version')
return
endNe laissez pas les gardes comme celle-ci en place comme correctif. Elles cachent le vrai problème, qui est un script et un framework qui ne correspondent pas.
Liste de contrôle
| Symptôme | Correction |
|---|---|
(global 'X') |
La fonction n'est pas définie dans le fichier ou n'a jamais été chargée : vérifiez le manifest et l'ordre de définition |
(field 'X') |
La table n'a pas cette entrée : vérifiez l'orthographe et la version du framework |
(method 'X') |
Mauvais objet ou deux-points utilisés à la place d'un point : vérifiez ce que la variable contient |
| Fonctionne d'un côté uniquement | La fonction existe uniquement du côté client ou uniquement du côté serveur |
| Erreur après une mise à jour du framework | Remplacez la fonction supprimée par la nouvelle, ou mettez à jour le script |
| L'appel à l'export retourne nil | Démarrez d'abord la resource fournie et vérifiez le nom de l'export |
Réponses rapides
Que signifie « attempt to call a nil value » ?
Le script a essayé d'exécuter quelque chose comme une fonction, mais le nom contient nil, donc il n'y a rien à exécuter. Le nom entre les crochets vous dit quelle fonction manque.
Quelle est la différence entre field, global et method dans cette erreur ?
Un global est un nom nu comme Foo(), un field est une entrée de table comme Config.Foo() ou ESX.Foo(), et une méthode est un appel avec deux-points comme obj:Foo(). Il vous dit seulement comment la fonction manquante a été atteinte.
Une mauvaise version de framework peut-elle la causer ?
Oui. Un script écrit pour une ancienne ou nouvelle version d'ESX, QBCore ou QBox peut appeler une fonction que votre version a renommée ou supprimée, ce qui laisse nil derrière.
Des scripts sans ce problème
Advanced BoostingDu boosting de véhicules piloté par tablette : contrats de classe D à S+, crews et file d’attente en direct.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 →
Item Creator V2Créez des items utilisables avec animations, props, effets et plus — sans écrire une ligne de code.Voir le script →