table index is nil / attempt to index a nil value (field): corregir Lua en FiveM
Corregir 'table index is nil' y 'attempt to index a nil value (field x)' en Lua de FiveM: claves de config faltantes, asignaciones t[nil], tablas anidadas y patrones de acceso seguro.
Dos errores que se ven parecidos surgen todo el tiempo en scripts de FiveM:
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')Significan cosas diferentes. El primero se trata de una clave nil, el segundo sobre una tabla nil. Ambos se reducen a un valor que tu código esperaba y no encontró. Esta guía muestra cómo distinguirlos y cómo escribir el acceso para que no pueda fallar.
table index is nil
Asignaste a una tabla, y la clave era nil:
local cache = {}
local function remember(identifier, data)
cache[identifier] = data -- table index is nil when identifier is nil
endLua permite cualquier valor como clave excepto nil (y NaN). Leer cache[nil] solo da nil, pero escribir en ella lanza el error.
Encuentra qué variable entre los paréntesis es nil en esa línea. Las fuentes habituales:
- Una búsqueda de jugador que no retornó nada.
GetPlayerIdentifierByType(source, 'license')retornanilcuando el jugador no tiene identificador de ese tipo, por ejemplo cuando el jugador no está conectado a través de la plataforma que esperas. - Un
sourceincorrecto. En el servidor, verifica que el evento realmente viene de un jugador. Una llamada desde la consola no tiene jugador detrás. - Un campo faltante en los datos:
data.ides nil porque el remitente usódata.Id.
Imprímelo para estar seguro:
print('identifier', identifier, type(identifier))Luego detén la asignación cuando la clave falta, y decide si eso es un error o un caso normal:
local function remember(identifier, data)
if not identifier then
return print('remember: no identifier, skipping')
end
cache[identifier] = data
endattempt to index a nil value (field 'x')
attempt to index a nil value (field 'shops')Aquí falta la tabla. El nombre entre paréntesis es el field que era nil, y la cosa que la indexaste está en la línea:
local first = Config.shops[1] -- Config.shops is nil, so [1] failsLua nombra lo que sabe. Algunas formas que verás:
| Mensaje | Significado |
|---|---|
(global 'Config') |
La variable global Config es nil |
(local 'data') |
Una variable local es nil, a menudo un argumento de función |
(field 'shops') |
Config.shops es nil |
(field '?') |
Una tabla encontrada por una clave variable, como Config.Shops[id], es nil |
(upvalue 'cache') |
Una variable de un alcance externo es nil |
Para field '?', Lua no puede nombrar la clave porque se calcula:
Config.Shops[id].label -- attempt to index a nil value (field '?')La solución es la misma: encuentra qué paso de la cadena es nil. Imprime cada paso:
print(Config)
print(Config.Shops)
print(Config.Shops[id])Tablas de config anidadas
La mayoría de estos errores provienen de archivos de configuración:
Config = {}
Config.Shops = {
bar = { label = 'Bar', items = { 'beer', 'water' } },
}
-- somewhere else
local items = Config.Shops[shopName].itemsSi shopName es 'Bar' en lugar de 'bar', Config.Shops[shopName] es nil y el siguiente .items se bloquea. Causas a verificar:
- Diferente ortografía o caso. Las claves de Lua distinguen mayúsculas y minúsculas.
- El archivo de configuración no se carga. Debe estar en
shared_scripts(o la lista del lado correcto) defxmanifest.lua, antes que el archivo que lo lee. - La config se define solo en un lado. Un archivo listado en
server_scriptses invisible para el cliente. - Una clave numérica contra una clave de cadena.
Config.Shops[1]yConfig.Shops['1']son entradas diferentes. Esto a menudo sucede después de que los datos pasan a través de JSON, ver errores de FiveM json.decode.
-- fxmanifest.lua
shared_scripts { 'config.lua' }
client_scripts { 'client/*.lua' }
server_scripts { 'server/*.lua' }Patrones de acceso seguro
Cuando un valor faltante es un caso normal, escribe el acceso para que lo maneje.
Verifica cada paso con and:
local shop = Config.Shops and Config.Shops[shopName]
if not shop then
return print(('Unknown shop: %s'):format(tostring(shopName)))
end
print(shop.label)Usa or para un valor predeterminado:
local items = (shop and shop.items) or {}
local radius = Config.Radius or 5.0Haz un pequeño asistente cuando lees caminos profundos a menudo:
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')Cuidado: no ocultes cada nil con
or {}. Si una tabla que debe existir falta, ese es un error en la config o el orden de carga, y un fallback silencioso solo mueve el error a algún lugar menos obvio. Usa guardias para valores que pueden estar legítimamente ausentes.
Vuelca una tabla para ver qué hay dentro
Cuando no estés seguro de lo que una tabla contiene, imprímela como JSON:
print(json.encode(Config.Shops, { indent = true }))Verás las claves reales y detectarás un error tipográfico, un caso diferente o un número donde esperabas una cadena. Hazlo en el punto donde sucede el error, no al principio del archivo, porque los datos pueden llenarse después.
Lista de verificación
| Síntoma | Solución |
|---|---|
table index is nil |
La clave en t[key] = value es nil; imprímela y retorna temprano si falta |
attempt to index a nil value (field 'shops') |
El campo nombrado no se establece en la tabla antes de él; verifica el nombre y la ortografía |
attempt to index a nil value (field '?') |
Una búsqueda con una clave variable no encontró nada; verifica la clave y su caso |
| Funciona en el servidor, nil en el cliente | La config no está en shared_scripts |
| Archivo de config ignorado | Enuméralo antes de los archivos que lo usan |
| Clave numérica vs clave de cadena | [1] y ['1'] difieren; convierte con tonumber o tostring |
Para los otros mensajes nil comunes, ver attempt to compare nil y errores de argumentos incorrectos.
Respuestas rápidas
¿Qué significa 'table index is nil'?
El script intentó escribir en una tabla usando nil como la clave, como t[key] = value cuando key es nil. Lua no permite nil como clave, así que se detiene.
¿Cuál es la diferencia entre 'table index is nil' y 'attempt to index a nil value'?
En 'table index is nil' la clave es nil. En 'attempt to index a nil value' la tabla en sí es nil, así que no hay nada para leer o escribir.
¿Por qué el error dice field '?' en lugar de un nombre?
Cuando la clave es una variable como Config.Shops[id], Lua no puede nombrarla. Muestra ?. Mira la línea y encuentra qué parte de la cadena es nil.
Scripts que evitan este problema
Shop CreatorCrea una tienda en menos de un minuto — dueños, empleados, caja fuerte y atracos.Ver script →
Quest CreatorUn editor visual de misiones y diálogos con NPC, nodo a nodo dentro del juego.Ver script →
Item Creator V2Crea items usables con animaciones, props, efectos y más — sin escribir código.Ver script →