Roblox Studio syntax error

Cannot use '...' outside of a vararg function

What Cannot use '...' outside of a vararg function means in Roblox Studio, the three things that cause it with the code that triggers each, and the fix for each one.

Updated 5 November 20263 min readSyntax errorLuauWritten by

In short

... means "all the extra arguments this function was given". Only a function that lists ... in its own brackets has them. Luau found ... in a function that does not, most often an inner function written inside the one that does, such as the callback of task.delay, task.spawn or :Connect. Inner functions do not inherit the outer function's ....

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.Logger:4: Cannot use '...' outside of a vararg function

It is a syntax error, so the script does not run at all. The line and column point at the ... that cannot be used there.

The main body of a script is allowed to use ...: in a ModuleScript or Script it is simply empty. The error only comes from inside a function that does not declare it.

Causes and fixes

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

... used inside an inner function

The outer function has ..., but the callback written inside it is a new function with its own, empty argument list.

Breaks Script in ServerScriptService named Logger
local function logLater(...)
	task.delay(1, function()
		print("[log]", ...)
	end)
end

logLater("Round", 3, "started")

Save the arguments in a table in the outer function with table.pack(...), and unpack them in the inner one. Or pass them on: task.delay(1, print, "[log]", ...).

Fixed Script in ServerScriptService named Logger
local function logLater(...: any)
	local args = table.pack(...)
	task.delay(1, function()
		print("[log]", table.unpack(args, 1, args.n))
	end)
end

logLater("Round", 3, "started")

table.pack stores the count in n, so nil arguments in the middle are kept when you unpack with 1, args.n.

The function never lists ... in its brackets

Code copied from a function that took ... into one with named parameters, or a parameter list edited later, leaves ... with nothing to refer to.

Breaks Script in ServerScriptService named Announcer
local function announce(message)
	-- announce has no ... in its brackets
	print(message, select("#", ...), "extra values")
end

announce("Hello")

Add ... as the last parameter if the function should take extra arguments, or name every parameter instead.

Fixed Script in ServerScriptService named Announcer
local function announce(message: string, ...: any)
	print(message, select("#", ...), "extra values")
end

announce("Hello", 1, 2)

An event callback reads the outer arguments

A RemoteEvent handler built inside a helper that takes ... cannot read those values from inside the handler.

Breaks Script in ServerScriptService named RemoteLog
local function bindLogger(remote, ...)
	remote.OnServerEvent:Connect(function(player)
		print(player.Name, ...)
	end)
end

bindLogger(Instance.new("RemoteEvent"), "tag")

Pack the values first, or let the callback take its own ... if you meant the arguments the event passes.

Fixed Script in ServerScriptService named RemoteLog
local function bindLogger(remote: RemoteEvent, ...: any)
	local tags = table.pack(...)
	remote.OnServerEvent:Connect(function(player: Player, ...: any)
		print(player.Name, table.unpack(tags, 1, tags.n), ...)
	end)
end

bindLogger(Instance.new("RemoteEvent"), "tag")

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.Logger:4: Cannot use '...' outside of a vararg function

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 ... mean in Luau?

It stands for the extra arguments passed to a function that lists ... as its last parameter. You can pass it on, count it with select("#", ...) or store it with table.pack(...).

Why can my inner function not see ...?

Every function has its own .... Local variables from the outer function are visible inside, so copy the values into a local table first.

Can RoCode fix it?

Yes. Paste the Output line into RoCode. It reads the script in your open place and passes the values to the inner function correctly.

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, 5 November 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 5 November 2026. A type check catches misspelt APIs and wrong types, not game logic, so playtest in Studio before you publish.

More Roblox errors

All Roblox Studio errors

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.