Lua syntax error: unexpected symbol near, 'end' expected (FiveM)

FiveM resource failing with a Lua syntax error? What 'unexpected symbol near', 'end expected' and 'unfinished string' mean, how to find the line and lint your code.

When a resource loads and one of its files cannot be parsed, the console prints something like this:

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

This is a syntax error: the file is not valid Lua, so nothing in it runs. It is different from a runtime error such as attempt to call a nil value, which happens while the code is running. Here is what the common messages mean and how to find the line.

Read the message

Every syntax error has the same parts:

text
@my_script/server/main.lua:48: unexpected symbol near '<'
  • @my_script/server/main.lua is the file, inside the resource.
  • 48 is the line where the parser gave up. The real mistake is often on that line or on the line above.
  • near '<' is the token the parser was reading when it failed. Search for it in the file.

For the general way of reading console errors, see how to read a FiveM script error.

unexpected symbol near

The parser found something that cannot start or continue a statement. The usual causes:

  • The file is not Lua. If it says near '<', you may have saved an HTML page instead of the raw file, for example from a code hosting website. Open the file and check its first lines.
  • Merge conflict markers such as <<<<<<< and >>>>>>> left behind after combining two versions.
  • A stray character from copying code out of a chat or a web page: a curly quote, an odd space, a leftover bracket.
  • Code from another language, such as != instead of ~=, or && instead of and.
lua
-- wrong
if price != 0 then end

-- right
if price ~= 0 then end

Tip: FiveM's Lua accepts a few additions to standard Lua, for example compound assignment such as count += 1. A plain Lua linter may still flag them. If your editor complains about a line that works on the server, that is usually why.

'end' expected

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

A block (function, if, for, while, do) was opened and never closed. Lua only finds out when it reaches the end of the file, which is the <eof> at the end of the message.

The part in brackets is the useful one: it names the block and the line where it started. Go to line 12 and follow that block down until you find where an end is missing. Lining up the indentation makes it obvious:

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

The opposite mistake exists too: one end too many gives '<eof>' expected near 'end'.

The same logic applies to brackets. '}' expected (to close '{' at line 20) means a table was not closed, and ')' expected near means a call or condition is missing its closing bracket. A missing comma between two table entries produces the same kind of message:

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''

The parser expected an assignment and found a value instead. A frequent case is a table entry with a key but no =:

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

A line that is only a name or a value, such as Config.Debug true, usually gives syntax error near instead. The fix is the same: find what is missing or mistyped on that line.

unfinished string

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

A string was opened with a quote and the line ended before it was closed. Typical causes are a missing closing quote, or an apostrophe inside a single-quoted string:

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'

For text that spans several lines, use a long string, since a normal string cannot contain a line break:

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

Find the line faster

Do not read the whole file. Open the file at the reported line, then:

  1. Look at the line itself and the line above.
  2. If the message mentions a line in brackets, start from that line instead.
  3. Comment out half of the file, then reload. Whether the error remains tells you which half has the mistake.

A better habit is catching these before you restart the server. Install an editor with Lua support, such as VS Code with a Lua language server extension, and set its Lua version to 5.4 to match FiveM. It underlines unclosed blocks and missing brackets as you type. A setup guide is in setting up VS Code for FiveM.

If you have the standard Lua tools installed, luac -p file.lua checks the syntax of a file without running it.

Checklist

Symptom Fix
unexpected symbol near '<' The file is HTML or has merge conflict markers; get the raw file again
unexpected symbol near a strange character A pasted curly quote or odd character; retype the line
'end' expected (to close 'function' at line N) near <eof> Go to line N and find the block missing its end
'<eof>' expected near 'end' One end too many; check indentation above it
'=' expected near A table key without =, or a missing comma before it
unfinished string near A missing closing quote, or an apostrophe inside the string
!= or && in the code Use ~= and and

Quick answers

What does 'unexpected symbol near' mean in Lua?

The Lua parser found a character or word where it cannot go. The text after near is the exact token it stopped at. The real mistake is on that line or the line just before it.

Why does 'end expected' point to a different line than the mistake?

Lua only notices a missing end when it reaches the end of the file. The part in brackets, such as to close 'function' at line 12, tells you which block was never closed.

Why does a script fail to load with a syntax error but never reaches runtime?

A syntax error stops the whole file from being parsed, so none of its code runs. Fix the error and the resource loads again.

Scripts that skip this problem

Quest CreatorA visual editor for quests and NPC dialogues, built node by node in game.View script β†’Item Creator V2Create usable items with animations, props, effects and more β€” without writing code.View script β†’Shop CreatorBuild a shop in under a minute β€” owners, employees, vaults and robberies included.View script β†’

Keep reading