índice de tabela é nil / índice um valor nil (campo): correção FiveM Lua

Corrija 'table index is nil' e 'attempt to index a nil value (field x)' em Lua FiveM: chaves de config faltando, atribuições t[nil], tabelas aninhadas e padrões de acesso seguro.

Dois erros que parecem iguais surgem o tempo todo em scripts FiveM:

text
SCRIPT ERROR: @my_script/server/main.lua:42: table index is nil
SCRIPT ERROR: @my_script/client/main.lua:19: attempt to index a nil value (field 'shops')

Eles significam coisas diferentes. O primeiro é sobre uma chave nil, o segundo sobre uma tabela nil. Ambos se resumem a um valor que seu código esperava e não encontrou. Este guia mostra como distingui-los e como escrever o acesso para que não consiga travar.

índice de tabela é nil

Você atribuiu a uma tabela, e a chave era nil:

lua
local cache = {}

local function remember(identifier, data)
    cache[identifier] = data     -- table index is nil when identifier is nil
end

Lua permite qualquer valor como chave exceto nil (e NaN). Ler cache[nil] apenas dá nil, mas escrever em uma levanta o erro.

Encontre qual variável entre os colchetes é nil naquela linha. As fontes usuais:

  • Uma busca de jogador que retornou nada. GetPlayerIdentifierByType(source, 'license') retorna nil quando o jogador não tem identificador desse tipo, por exemplo quando o jogador não está conectado através da plataforma que você espera.
  • Um source errado. No servidor, verifique se o evento realmente vem de um jogador. Uma chamada do console não tem jogador por trás disso.
  • Um campo faltando nos dados: data.id é nil porque o remetente usou data.Id.

Imprima para ter certeza:

lua
print('identifier', identifier, type(identifier))

Então pare a atribuição quando a chave está faltando, e decida se isso é um erro ou um caso normal:

lua
local function remember(identifier, data)
    if not identifier then
        return print('remember: no identifier, skipping')
    end
    cache[identifier] = data
end

tentativa de indexar um valor nil (campo 'x')

text
attempt to index a nil value (field 'shops')

Aqui a tabela está faltando. O nome entre colchetes é o campo que era nil, e a coisa que você indexou é na linha:

lua
local first = Config.shops[1]    -- Config.shops is nil, so [1] fails

Lua nomeia o que sabe. Algumas formas que você verá:

Mensagem Significado
(global 'Config') A variável global Config é nil
(local 'data') Uma variável local é nil, frequentemente um argumento de função
(field 'shops') Config.shops é nil
(field '?') Uma tabela encontrada por uma chave variável, como Config.Shops[id], é nil
(upvalue 'cache') Uma variável de um escopo externo é nil

Para field '?', Lua não consegue nomear a chave porque é computada:

lua
Config.Shops[id].label          -- attempt to index a nil value (field '?')

A correção é a mesma: encontre qual passo da cadeia é nil. Imprima cada passo:

lua
print(Config)
print(Config.Shops)
print(Config.Shops[id])

Tabelas config aninhadas

A maioria desses erros vêm de arquivos de config:

lua
Config = {}
Config.Shops = {
    bar = { label = 'Bar', items = { 'beer', 'water' } },
}

-- somewhere else
local items = Config.Shops[shopName].items

Se shopName é 'Bar' em vez de 'bar', Config.Shops[shopName] é nil e o próximo .items trava. Causas a verificar:

  1. Ortografia ou caso diferente. Chaves de Lua são sensíveis a caso.
  2. O arquivo config não é carregado. Deve estar em shared_scripts (ou a lista do lado certo) de fxmanifest.lua, antes do arquivo que o lê.
  3. O config é definido em um lado apenas. Um arquivo listado sob server_scripts é invisível para o cliente.
  4. Uma chave numérica contra uma chave de string. Config.Shops[1] e Config.Shops['1'] são entradas diferentes. Isso frequentemente acontece após dados passar através de JSON, veja erros FiveM json.decode.
lua
-- fxmanifest.lua
shared_scripts { 'config.lua' }
client_scripts { 'client/*.lua' }
server_scripts { 'server/*.lua' }

Padrões de acesso seguro

Quando um valor faltando é um caso normal, escreva o acesso para lidar com isso.

Verifique cada passo com and:

lua
local shop = Config.Shops and Config.Shops[shopName]
if not shop then
    return print(('Unknown shop: %s'):format(tostring(shopName)))
end
print(shop.label)

Use or para um padrão:

lua
local items = (shop and shop.items) or {}
local radius = Config.Radius or 5.0

Faça um pequeno ajudante quando você lê caminhos profundos frequentemente:

lua
local function get(t, ...)
    for _, key in ipairs({ ... }) do
        if type(t) ~= 'table' then return nil end
        t = t[key]
    end
    return t
end

local label = get(Config, 'Shops', shopName, 'label')

Atenção: não oculte cada nil com or {}. Se uma tabela que deve existir está faltando, isso é um bug no config ou na ordem de carga, e um fallback silencioso apenas move o erro para algum lugar menos óbvio. Use guardas para valores que podem legitimamente estar ausentes.

Despeje uma tabela para ver o que está dentro

Quando você não tem certeza do que uma tabela contém, imprima-a como JSON:

lua
print(json.encode(Config.Shops, { indent = true }))

Você verá as chaves reais e verá um erro de digitação, um caso diferente ou um número onde você esperava uma string. Faça isso no ponto onde o erro acontece, não no topo do arquivo, porque os dados podem ser preenchidos depois.

Checklist

Sintoma Correção
table index is nil A chave em t[key] = value é nil; imprima-a e retorne cedo se estiver faltando
attempt to index a nil value (field 'shops') O campo nomeado não está definido na tabela antes; verifique o nome e a ortografia
attempt to index a nil value (field '?') Uma busca com uma chave variável não encontrou nada; verifique a chave e seu caso
Funciona no servidor, nil no cliente O config não está em shared_scripts
Arquivo config ignorado Liste-o antes dos arquivos que o usam
Chave numérica vs chave de string [1] e ['1'] diferem; converta com tonumber ou tostring

Para as outras mensagens nil comuns, veja tentar comparar nil e erros de argumento inválido.

Respostas rápidas

O que significa 'table index is nil'?

O script tentou escrever em uma tabela usando nil como a chave, como t[key] = value quando key é nil. Lua não permite nil como uma chave, portanto para.

Qual é a diferença entre 'table index is nil' e 'attempt to index a nil value'?

Em 'table index is nil' a chave é nil. Em 'attempt to index a nil value' a tabela em si é nil, portanto não há nada para ler ou escrever.

Por que o erro diz campo '?' em vez de um nome?

Quando a chave é uma variável como Config.Shops[id], Lua não consegue nomeá-la. Mostra ?. Procure pela linha e encontre qual parte da cadeia é nil.

Scripts sem esse problema

Shop CreatorMonte uma loja em menos de um minuto — donos, funcionários, cofres e assaltos inclusos.Ver script →Quest CreatorUm editor visual de missões e diálogos com NPCs, montado nó por nó dentro do jogo.Ver script →Item Creator V2Crie itens usáveis com animações, props, efeitos e muito mais — sem escrever código.Ver script →

Continue lendo