Error de sintaxis de Lua: símbolo inesperado cerca, 'end' esperado (FiveM)

¿Recurso de FiveM fallando con un error de sintaxis de Lua? Qué significan 'unexpected symbol near', 'end expected' y 'unfinished string', cómo encontrar la línea y lint tu código.

Cuando un recurso se carga y uno de sus archivos no se puede analizar, la consola imprime algo como esto:

text
Error parsing script @my_script/server/main.lua in resource my_script: @my_script/server/main.lua:48: unexpected symbol near '<'

Este es un error de sintaxis: el archivo no es Lua válido, así que nada en él se ejecuta. Es diferente de un error en tiempo de ejecución como attempt to call a nil value, que sucede mientras el código se está ejecutando. Aquí está lo que significan los mensajes comunes y cómo encontrar la línea.

Lee el mensaje

Cada error de sintaxis tiene las mismas partes:

text
@my_script/server/main.lua:48: unexpected symbol near '<'
  • @my_script/server/main.lua es el archivo, dentro del recurso.
  • 48 es la línea donde el analizador se rindió. El error real a menudo está en esa línea o en la anterior.
  • near '<' es el token que el analizador estaba leyendo cuando falló. Búscalo en el archivo.

Para la forma general de leer errores de consola, ver cómo leer un error de script de FiveM.

unexpected symbol near

El analizador encontró algo que no puede comenzar o continuar una declaración. Las causas habituales:

  • El archivo no es Lua. Si dice near '<', es posible que hayas guardado una página HTML en lugar del archivo sin procesar, por ejemplo desde un sitio web de alojamiento de código. Abre el archivo y verifica sus primeras líneas.
  • Marcadores de conflicto de fusión como <<<<<<< y >>>>>>> dejados atrás después de combinar dos versiones.
  • Un carácter extraño de copiar código de un chat o una página web: una comilla rizada, un espacio extraño, un paréntesis sobrante.
  • Código de otro idioma, como != en lugar de ~=, o && en lugar de and.
lua
-- wrong
if price != 0 then end

-- right
if price ~= 0 then end

Consejo: Lua de FiveM acepta algunos complementos a Lua estándar, por ejemplo asignación compuesta como count += 1. Un linter de Lua simple aún puede señalarlos. Si tu editor se queja de una línea que funciona en el servidor, esa es usualmente la razón.

'end' expected

text
@my_script/client/main.lua:130: 'end' expected (to close 'function' at line 12) near <eof>

Un bloque (function, if, for, while, do) se abrió y nunca se cerró. Lua solo se da cuenta cuando llega al final del archivo, que es el <eof> al final del mensaje.

La parte entre paréntesis es la útil: nombra el bloque y la línea donde comenzó. Ve a la línea 12 y sigue ese bloque hacia abajo hasta que encuentres donde falta un end. Alinear la sangría lo hace obvio:

lua
function OpenShop(id)            -- line 12
    if Config.Shops[id] then
        ShowMenu(id)
    -- the 'end' for this 'if' is missing
end                              -- this one closes the 'if', so the function is never closed

El error opuesto también existe: un end de más da '<eof>' expected near 'end'.

La misma lógica se aplica a los paréntesis. '}' expected (to close '{' at line 20) significa que una tabla no se cerró, y ')' expected near significa que una llamada o condición le falta su paréntesis de cierre. Una coma faltante entre dos entradas de tabla produce el mismo tipo de mensaje:

lua
Config.Shops = {
    { name = 'Bar', price = 10 }    -- missing comma
    { name = 'Cafe', price = 12 },
}

'=' expected near

text
@my_script/shared/config.lua:9: '=' expected near ''bar''

El analizador esperaba una asignación y encontró un valor en su lugar. Un caso frecuente es una entrada de tabla con una clave pero sin =:

lua
Config.Prices = {
    ['burger'] 10,      -- wrong: missing =
    ['water'] = 5,
}

Una línea que es solo un nombre o un valor, como Config.Debug true, generalmente da syntax error near en su lugar. La solución es la misma: encuentra qué falta o está mal escrito en esa línea.

unfinished string

text
@my_script/client/main.lua:33: unfinished string near '"You need '

Una cadena se abrió con una comilla y la línea terminó antes de que se cerrara. Las causas típicas son una comilla de cierre faltante, o un apóstrofo dentro de una cadena entre comillas simples:

lua
-- wrong: the apostrophe ends the string
local msg = 'You can't do that'

-- right
local msg = "You can't do that"
local msg2 = 'You can\'t do that'

Para el texto que abarca varias líneas, usa una cadena larga, ya que una cadena normal no puede contener un salto de línea:

lua
local help = [[
Line one
Line two
]]

Encuentra la línea más rápido

No leas todo el archivo. Abre el archivo en la línea reportada, luego:

  1. Mira la línea en sí y la línea anterior.
  2. Si el mensaje menciona una línea entre paréntesis, comienza desde esa línea en su lugar.
  3. Comenta la mitad del archivo, luego recarga. Si el error permanece te dice cuál mitad tiene el error.

Un mejor hábito es atrapar estos antes de que reinicies el servidor. Instala un editor con soporte de Lua, como VS Code con una extensión de servidor de lenguaje Lua, y establece su versión de Lua a 5.4 para que coincida con FiveM. Subraya bloques sin cerrar y paréntesis faltantes mientras escribes. Una guía de configuración está en configurar VS Code para FiveM.

Si tienes las herramientas de Lua estándar instaladas, luac -p file.lua verifica la sintaxis de un archivo sin ejecutarlo.

Lista de verificación

Síntoma Solución
unexpected symbol near '<' El archivo es HTML o tiene marcadores de conflicto de fusión; obtén el archivo sin procesar nuevamente
unexpected symbol near un carácter extraño Una comilla rizada pegada u otro carácter extraño; vuelve a escribir la línea
'end' expected (to close 'function' at line N) near <eof> Ve a la línea N y encuentra el bloque que le falta su end
'<eof>' expected near 'end' Un end de más; verifica la sangría arriba
'=' expected near Una clave de tabla sin =, o una coma faltante antes de ella
unfinished string near Una comilla de cierre faltante, o un apóstrofo dentro de la cadena
!= o && en el código Usa ~= y and

Respuestas rápidas

¿Qué significa 'unexpected symbol near' en Lua?

El analizador de Lua encontró un carácter o palabra donde no puede ir. El texto después de near es el token exacto en el que se detuvo. El error real está en esa línea o la línea anterior.

¿Por qué 'end expected' apunta a una línea diferente que el error?

Lua solo nota un end faltante cuando llega al final del archivo. La parte entre paréntesis, como to close 'function' at line 12, te dice qué bloque nunca se cerró.

¿Por qué un script falla al cargar con un error de sintaxis pero nunca alcanza el tiempo de ejecución?

Un error de sintaxis detiene que todo el archivo se analice, así que ninguno de sus códigos se ejecuta. Corrige el error y el recurso se carga nuevamente.

Scripts que evitan este problema

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 →Shop CreatorCrea una tienda en menos de un minuto — dueños, empleados, caja fuerte y atracos.Ver script →

Sigue leyendo