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

¿Obteniendo 'bad argument #1 to X (number expected, got nil)' en FiveM? Cómo leer el número de argumento y corregir entidades nil, pairs(nil), tonumber y errores de tabla.

En algún lugar de tu consola, un script se detiene con esto:

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

Una función fue llamada con un argumento que no puede usar, y el argumento es casi siempre nil. El mensaje te dice qué función, qué argumento y qué tipo quería. Esta guía muestra cómo leerlo y las fuentes habituales de nil.

Cómo leer el mensaje

text
bad argument #1 to 'X' (number expected, got nil)
  • X es el nombre de la función que se quejó.
  • #1 es la posición del argumento: #1 es el primero, #2 el segundo.
  • number expected es el tipo que la función necesita. También puede decir string, table o boolean.
  • got nil es lo que realmente recibió. También puede ser got table, got string o got no value.

Abre la línea del error y busca la función nombrada en el mensaje. Luego mira el argumento en esa posición y pregúntate de dónde viene.

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

Aquí Config.Prices[item] es nil, porque item no es una clave de la tabla. El error está en la línea math.floor, pero el error está en los datos.

table expected, got nil

El mismo mensaje con una tabla aparece con funciones de table:

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

Crea la tabla antes de usarla:

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

Para una tabla que vive en una estructura compartida, créala cuando falte:

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

Bucle sobre nil: pairs e ipairs

En Lua 5.3 y 5.4, que FiveM usa, hacer un bucle sobre nil falla con un mensaje que nombra el bucle en lugar de pairs:

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

Verifica dónde se define la tabla: un error tipográfico en el nombre, el archivo de configuración no se carga por el manifiesto, o datos que aún no han llegado. Un pequeño guardián evita el bloqueo mientras encuentras la causa real:

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

Úsalo como una red de seguridad, no como una solución. Si Config.Jobs debería existir, un bucle vacío solo oculta el error. El mensaje relacionado tabla index es nil cubre claves faltantes en tablas de configuración anidadas.

Nativos que reciben nil

Muchos nativos necesitan un número, como un identificador de entidad. Un identificador que es nil o 0 generalmente significa que la entidad no existe (aún).

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

Fuentes comunes:

  • La entidad no está cargada. Un vehículo spawneado por el servidor no está disponible para tu cliente por un momento. En el cliente, espera hasta que exista:
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 función no retornó nada. GetPlayerPed(-1), GetClosestVehicle y similares pueden retornar 0 cuando nada coincide. Verifica el valor antes de usarlo.
  • Un vector incorrecto. Un nativo que quiere tres números, x, y, z, no acepta una tabla entera. Pasa coords.x, coords.y, coords.z, o usa vector3 donde el nativo toma uno.
  • Una clave faltante en la configuración. Config.Spawn.x es nil cuando Config.Spawn se escribe con [1], [2], [3].

El texto exacto depende del nativo, y algunos nativos no lanzan un error en absoluto pero no hacen nada. Por eso vale la pena agregar un guardián:

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

tostring, tonumber y string.format

Las funciones de conversión son otra fuente de nil:

  • tonumber('abc') retorna nil, no un error, así que el bloqueo viene después cuando usas el resultado.
  • tostring(value) siempre retorna una cadena, incluso para nil (da 'nil'), así que es seguro usar cuando construyes un texto.
  • string.format('%d', value) falla cuando value es nil: bad argument #2 to 'format' (number expected, got nil).

Cuando un número viene de un jugador o de un comando, verifica:

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 que args[1] es nil cuando el jugador escribió /pay solo, y tonumber(nil) retorna nil, así que la verificación anterior cubre ambos casos.

Encuentra el nil

Cuando la fuente no es obvia, imprime los valores justo antes de la línea que falla:

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

Luego rastrea el nil de nuevo a donde debería haber sido establecido. Elimina los prints cuando hayas terminado.

Lista de verificación

Síntoma Solución
bad argument #1 to 'floor' (number expected, got nil) El valor falta: verifica la clave o variable que la alimenta
bad argument #1 to 'insert' (table expected, got nil) Crea la tabla primero: t = t or {}
bad argument #1 to 'for iterator' (table expected, got nil) La tabla sobre la que haces un bucle es nil; verifica su nombre y dónde se llena
Un nativo falla en una entidad Verifica DoesEntityExist(entity) y espera a que la entidad se cargue
tonumber(...) da nil Valida la entrada del jugador antes de usarla
bad argument #2 to 'format' %d y %s necesitan un valor real; verifica el argumento en esa posición

Si el error es sobre algo que es nil en lugar de un argumento incorrecto, lee attempt to compare nil y attempt to call a nil value.

Respuestas rápidas

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

Una función recibió nil como su primer argumento donde necesita un número. X es la función, #1 es la posición del argumento, y nil es lo que tu código pasó.

¿Cómo corrijo 'bad argument #1 to for iterator (table expected, got nil)'?

Hiciste un bucle sobre una variable que es nil con pairs o ipairs. Encuentra dónde se llena esa variable y verifica que existe, o haz un bucle sobre variable or {}.

¿Puede un nativo recibir nil sin un error?

Dependiendo del nativo, un valor nil o inválido puede ser tratado como 0 o simplemente no hacer nada, así que el error puede ocultarse. Verifica una entidad con DoesEntityExist(entity) antes de usarla.

Scripts que evitan este problema

Advanced BoostingBoosting de vehículos desde una tablet: contratos de clase D a S+, crews y cola en vivo.Ver script →CCTV Security CamerasCámaras colocables, una tablet con vista múltiple en vivo y fotos como prueba.Ver script →Item Creator V2Crea items usables con animaciones, props, efectos y más — sin escribir código.Ver script →

Sigue leyendo