Roblox Studio syntax error

Expected ')' (to close '(' at line 1), got <eof>

What Expected ')' (to close '(' at line 1), got <eof> 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

A ( was opened on the line the message names and never closed. got <eof> means Luau reached the end of the script still looking for the ); got 'local' means it found the next statement instead. By far the most common case is an event connection: :Connect(function() ... end needs a ) after its end, written end).

  • Go to the line in (to close '(' at line N): that is where the unclosed bracket starts.
  • For Connect(function(), the closing pair is end).
  • The whole script does not run until it is fixed, not just that line.
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.KillBrick:4: Expected ')' (to close '(' at line 1), got <eof>

Other forms of the same message:

  • Expected ')' (to close '(' at line 3), got 'local'
  • Expected '}' (to close '{' at line 1), got <eof>
  • Expected ']' to match an opening '['

Brackets come in pairs: ( ) for calls and grouping, { } for tables, [ ] for keys. When Luau reaches something that cannot be inside the open bracket, it stops reading and reports the bracket it was still waiting to close.

The line number at the start of the Output line is where Luau gave up, which can be much further down. The number inside the message, at line N, is the one to go to.

Causes and fixes

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

end instead of end) after Connect(function()

part.Touched:Connect(function(hit) opens a bracket for Connect, then a function. The function closes with end, and the call still needs its ).

Breaks Script in a Part in Workspace named KillBrick
local part = script.Parent

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

Close the call after the function: end).

Fixed Script in a Part in Workspace named KillBrick
local part = script.Parent :: BasePart

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

A call or a string inside it is not closed

A print( or Vector3.new( missing its ) makes Luau read the next line as part of the call. A missing closing quote does the same, and Luau reports both.

Breaks Script in ServerScriptService named Spawner
local part = Instance.new("Part")
part.Position = Vector3.new(0, 10, 0
part.Parent = workspace

Add the missing ) at the end of the call.

Fixed Script in ServerScriptService named Spawner
local part = Instance.new("Part")
part.Position = Vector3.new(0, 10, 0)
part.Parent = workspace

A table is missing its } or a comma

The same rule for tables: { needs }, and items inside need commas. A missing comma gives Expected ',' after table constructor element first.

Breaks ModuleScript in ReplicatedStorage named Settings
local settings = {
	WalkSpeed = 16,
	JumpPower = 50
	Gravity = 196.2,
}

Put a comma after every item (one after the last is allowed), and close the table with }.

Fixed ModuleScript in ReplicatedStorage named Settings
local settings = {
	WalkSpeed = 16,
	JumpPower = 50,
	Gravity = 196.2,
}

return settings

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.KillBrick:4: Expected ')' (to close '(' at line 1), got <eof>

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

Which line is the problem?

The one in (to close '(' at line N). The line number at the start of the Output line is only where Luau gave up looking.

What does got eof mean in the message?

End of file:. Luau reached the end of the script and the bracket was still open.

Why does the whole script stop working?

A syntax error means Luau cannot read the script, so none of it runs, not even the lines above the mistake.

Can RoCode fix it?

Yes. Paste the Output line into RoCode. It opens the script in your open place, finds the unclosed bracket and closes it in the right spot.

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.