argumento inválido #1 para 'X' (número esperado, recebido nil): correção FiveM Lua

Obtendo 'bad argument #1 to X (number expected, got nil)' no FiveM? Como ler o número do argumento e corrigir entidades nil, pairs(nil), tonumber e erros de tabela.

Em algum lugar do seu console, um script para com isto:

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

Uma função foi chamada com um argumento que não consegue usar, e o argumento é quase sempre nil. A mensagem diz qual função, qual argumento e que tipo queria. Este guia mostra como lê-la e as fontes usuais do nil.

Como ler a mensagem

text
bad argument #1 to 'X' (number expected, got nil)
  • X é o nome da função que reclamou.
  • #1 é a posição do argumento: #1 é o primeiro, #2 o segundo.
  • number expected é o tipo que a função precisa. Também pode dizer string, table ou boolean.
  • got nil é o que realmente recebeu. Também pode ser got table, got string ou got no value.

Abra a linha do erro e procure a função nomeada na mensagem. Então procure o argumento nessa posição e pergunte onde ela vem.

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

Aqui Config.Prices[item] é nil, porque item não é uma chave da tabela. O erro está na linha math.floor, mas o erro está nos dados.

table expected, got nil

A mesma mensagem com uma tabela aparece com funções de table:

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

Crie a tabela antes de usá-la:

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

Para uma tabela que reside em uma estrutura compartilhada, crie-a quando estiver faltando:

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

Fazendo loop sobre nil: pairs e ipairs

Em Lua 5.3 e 5.4, que FiveM usa, fazer loop sobre nil falha com uma mensagem que nomeia o loop em vez 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

Verifique onde a tabela é definida: um erro de digitação no nome, o arquivo de config não carregado pelo manifest, ou dados que não chegaram ainda. Um guarda curto evita o crash enquanto você encontra a causa real:

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

Use-o como uma rede de segurança, não como uma correção. Se Config.Jobs deveria existir, um loop vazio apenas oculta o bug. A mensagem relacionada índice de tabela é nil cobre chaves faltando em tabelas de config aninhadas.

Natives que recebem nil

Muitos natives precisam de um número, como um identificador de entidade. Um identificador que é nil ou 0 geralmente significa que a entidade não existe (ainda).

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

Fontes comuns:

  • A entidade não é carregada. Um veículo desovado pelo servidor não está disponível para seu cliente por um momento. No cliente, aguarde até 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
  • Uma função retornou nada. GetPlayerPed(-1), GetClosestVehicle e similares podem retornar 0 quando nada corresponde. Verifique o valor antes de usá-lo.
  • Um vetor errado. Um native que quer três números, x, y, z, não aceita uma tabela inteira. Passe coords.x, coords.y, coords.z, ou use um vector3 onde o native recebe um.
  • Uma chave faltando no config. Config.Spawn.x é nil quando Config.Spawn é escrito com [1], [2], [3].

O texto exato depende do native, e alguns natives não levantam um erro em tudo mas não fazem nada. É por isso que um guarda vale a pena adicionar:

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

tostring, tonumber e string.format

Funções de conversão são outra fonte de nil:

  • tonumber('abc') retorna nil, não um erro, portanto o crash vem depois quando você usa o resultado.
  • tostring(value) sempre retorna uma string, mesmo para nil (fornece 'nil'), portanto é seguro usar quando você constrói um texto.
  • string.format('%d', value) falha quando value é nil: bad argument #2 to 'format' (number expected, got nil).

Quando um número vem de um jogador ou de um comando, verifique:

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)

Note args[1] é nil quando o jogador digitou /pay sozinho, e tonumber(nil) retorna nil, portanto a verificação acima cobre ambos os casos.

Encontre o nil

Quando a fonte não é óbvia, imprima os valores logo antes da linha falhando:

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

Então rastreie o nil de volta para onde deveria ter sido definido. Remova as impressões quando terminar.

Checklist

Sintoma Correção
bad argument #1 to 'floor' (number expected, got nil) O valor está faltando: verifique a chave ou variável que o alimenta
bad argument #1 to 'insert' (table expected, got nil) Crie a tabela primeiro: t = t or {}
bad argument #1 to 'for iterator' (table expected, got nil) A tabela sobre a qual você faz loop é nil; verifique seu nome e onde é preenchida
Um native falha em uma entidade Verifique DoesEntityExist(entity) e aguarde a entidade carregar
tonumber(...) dá nil Valide entrada do jogador antes de usá-la
bad argument #2 to 'format' %d e %s precisam de um valor real; verifique o argumento nessa posição

Se o erro for sobre algo ser nil em vez de um argumento inválido, leia tentar comparar nil e tentar chamar um valor nil.

Respostas rápidas

O que significa 'bad argument #1 to X (number expected, got nil)'?

Uma função recebeu nil como seu primeiro argumento onde precisa de um número. X é a função, #1 é a posição do argumento, e nil é o que seu código passou.

Como corrijo 'bad argument #1 to for iterator (table expected, got nil)'?

Você fez um loop sobre uma variável que é nil com pairs ou ipairs. Encontre onde essa variável é preenchida e verifique se existe, ou faça um loop sobre variable or {}.

Um native pode receber nil sem um erro?

Dependendo do native, um valor nulo ou inválido pode ser tratado como 0 ou simplesmente não fazer nada, portanto o bug pode se esconder. Verifique uma entidade com DoesEntityExist(entity) antes de usá-la.

Scripts sem esse problema

Advanced BoostingBoosting de veículos pelo tablet: contratos da classe D à S+, crews e fila ao vivo.Ver script →CCTV Security CamerasCâmeras posicionáveis, um tablet com várias telas ao vivo e fotos impressas como prova.Ver script →Item Creator V2Crie itens usáveis com animações, props, efeitos e muito mais — sem escrever código.Ver script →

Continue lendo