Roblox Studio syntax error

Expected <eof>, got 'end'

What Expected <eof>, got 'end' means in Roblox Studio, the three things that cause it with the code that triggers each, and the fix for each one.

Updated 23 October 20263 min readSyntax errorLuau

In short

<eof> means end of file. Luau had already closed every block, so it expected the script to finish, and instead found another end (or an else). There is one too many. The most common reasons: an extra end after a function, an end put before an else, or a plain end left under an end).

On this page
  1. What it means
  2. Causes and fixes
  3. Fix it with RoCode
  4. Find the line
  5. Questions
  6. Sources

What the message means

Output (example)
ServerScriptService.Door:9: Expected <eof>, got 'end'

Other forms of the same message:

  • Expected <eof>, got 'else'
  • Expected <eof>, got 'elseif'

This is the opposite of Expected 'end' (to close ...), where an end is missing. Here every block is already closed and an extra one remains.

The line number is where the extra end is. But the block it was meant for may be higher up, where an end was put too early.

Causes and fixes

Three things cause this error in practice. Each one below has the smallest code that triggers it, then the fix.

An end before else or elseif

An if has one end, after its last branch. Putting an end after each branch closes the if early, and the else that follows has nothing to belong to, so Luau reports it (here got 'else') or the extra end after it.

Breaks Script in ServerScriptService named Shop
local coins = 50

if coins >= 100 then
	print("rich")
elseif coins >= 50 then
	print("ok")
end
else
	print("poor")
end

Write the whole chain as one block: if, any number of elseif, an optional else, then one end.

Fixed Script in ServerScriptService named Shop
local coins = 50

if coins >= 100 then
	print("rich")
elseif coins >= 50 then
	print("ok")
else
	print("poor")
end

An extra end after a function

Copying a block in or deleting an if leaves its end behind.

Breaks Script in ServerScriptService named Door
local function openDoor(door)
	door.Transparency = 0.5
	door.CanCollide = false
end
end

Delete the extra end. Indentation shows which block each end closes.

Fixed Script in ServerScriptService named Door
local function openDoor(door: BasePart)
	door.Transparency = 0.5
	door.CanCollide = false
end

print(openDoor)

A leftover end after end)

An event connection closes with end). Adding a plain end under it, out of habit or after moving code around, is one too many.

Breaks Script in a Part in Workspace named Pad
local pad = script.Parent

pad.Touched:Connect(function(hit)
	print(hit.Name)
end)
end

Delete the extra end: end) already closes both the function and the Connect( call.

Fixed Script in a Part in Workspace named Pad
local pad = script.Parent :: BasePart

pad.Touched:Connect(function(hit: BasePart)
	print(hit.Name)
end)

Fix it in your place

Paste the error, RoCode fixes it in your place

Copy the line from Output and paste it here. RoCode opens the script it names in the place you have open in Studio, works out which of the causes above it is, and edits the code there instead of handing you a snippet to paste.

For example: ServerScriptService.Door:9: Expected <eof>, got 'end'

RoCode is an AI agent for Roblox Studio: it reads the scripts in the place you have open, finds the line and edits it there, and every change is an undo point. It runs on Windows or macOS with a desktop browser. Free to start, with free credits every day.

How to find the line that causes it

  1. A syntax error stops the whole script before its first line runs, so nothing in that script works, not just the broken line.
  2. Open the script. The Script Editor underlines the problem in red; hover over the underline to read the message.
  3. Open Script Analysis (View tab) to see every syntax error in every script, with its line number. Double-click one to jump to it.
  4. The line number in the message is where Luau gave up, which is often below the real mistake. The (to close ... at line N) part points at the line where the unclosed bracket or block starts.

Questions

What does eof mean in the message?

End of file:. Luau thought the script was complete at that point.

Is it elseif or else if?

elseif, one word, for another condition in the same if. else if starts a new if inside the else and needs its own end.

When do I write end) and when end?

end) only when the function is written inside brackets, as in :Connect(function() ... end). Every other block ends with plain end. Writing end) after a plain function gives Expected identifier when parsing expression, got ')'.

Can RoCode fix it?

Yes. Paste the Output line into RoCode. It reads the script in your open place, works out which block the extra end belongs to and fixes the structure.

Sources and further reading

How the code was checked: every block marked Fixed passes Luau's strict type checker against Roblox's API definitions (luau-lsp, 23 October 2026), and every block marked Breaks compiles only to fail with the message on this page. The message wording was checked by compiling each broken block on this page with luau-compile, which uses the same Luau parser as Roblox Studio, on 23 October 2026. A type check catches misspelt APIs and wrong types, not game logic, so playtest in Studio before you publish.

Stop hunting errors line by line.

RoCode reads the scripts in your open place, fixes the error where it happens and tells you what it changed. Free every day, no card required.