In short
.. joins text, and it only accepts strings and numbers. The two types in the message are the left and right side: string with nil means the value on the right of .. was missing. Find out why it is nil, or turn it into text on purpose with tostring() or a backtick string such as `Coins: {coins}`, which never errors.
What the message means
StarterGui.ScreenGui.Coins.Label:6: attempt to concatenate string with nil
Other forms of the same message:
attempt to concatenate nil with stringattempt to concatenate string with Instanceattempt to concatenate string with boolean
Numbers are turned into text for you ("Coins: " .. 5 works). Everything else is not: nil, booleans, tables and Roblox objects all stop the script.
For a Roblox object, the message says Instance. You almost always wanted its .Name or one of its values, not the object.
Causes and fixes
Three things cause this error in practice. Each one below has the smallest code that triggers it, then the fix.
The value is nil
A value read from a table, an attribute or FindFirstChild can be nil. Joining it with .. fails, often in a UI label or a print you added to debug something else.
local label = script.Parent
local stats = { Coins = 120 }
-- "Gems" was never set: attempt to concatenate string with nil
label.Text = "Gems: " .. stats.Gems
Give the missing value a default, or skip the line when it is missing. Backtick strings print nil instead of failing, which is handy for debug prints.
local label = script.Parent :: TextLabel
local stats: { [string]: number } = { Coins = 120 }
local gems = stats.Gems or 0
label.Text = `Gems: {gems}`
An object was joined instead of its Name
A Player, Part or Tool is an Instance. "Hello " .. player gives attempt to concatenate string with Instance.
local Players = game:GetService("Players")
Players.PlayerAdded:Connect(function(player)
-- attempt to concatenate string with Instance
print("Welcome " .. player)
end)
Use the property you meant: player.Name, player.DisplayName or part.Name.
local Players = game:GetService("Players")
Players.PlayerAdded:Connect(function(player: Player)
print("Welcome " .. player.DisplayName)
end)
A true/false or a table was joined
.. does not turn true, false or a table into text. Settings flags and lists are the usual ones.
local settings = { Music = true, Volume = 0.5 }
-- attempt to concatenate string with boolean
print("Music on: " .. settings.Music)
Wrap it in tostring(), or use a backtick string. For a list, join its items with table.concat.
local settings = { Music = true, Volume = 0.5 }
local items = { "Sword", "Shield" }
print("Music on: " .. tostring(settings.Music))
print(`Volume: {settings.Volume}`)
print("Items: " .. table.concat(items, ", "))
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.
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
- Open Output (Window menu, or the Script tab), clear it with Ctrl+K (⌘K on Mac), and press Play.
- Find the first red line. It starts with the script's place in the Explorer and the line number, such as
ServerScriptService.Shop:12:. - Click the red line. Studio opens that script with the cursor on the failing line.
- Read the lines between
Stack BeginandStack Endunder it: they list the calls that led there, newest first, so you can see which function called the broken one. - Still not sure which value is wrong? Add
print(typeof(x), x)just above the line, or set a breakpoint on it and read the values in the Watch window.
Questions
Which side is nil?
The message lists the left side first, then the right. string with nil means the right side of .. was nil; nil with string means the left side.
What is the safest way to build text in Luau?
Backtick strings: `Coins: {coins}`. They call tostring on each value for you, so a nil prints as nil instead of stopping the script.
Why does joining a number work but not a boolean?
Luau turns numbers into text for .., but not booleans, nil, tables or objects. Use tostring() for those.
Can RoCode fix it?
Yes. Paste the Output line into RoCode. It finds the line in the script in your open place and fixes the value or the text, for example using .Name or a default.
Sources and further reading
- Roblox Creator Docs: strings. concatenation and string interpolation
- Roblox Creator Docs: tostring
- Luau: syntax (string interpolation)
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 and fails only when it runs. The message wording was checked by running the broken code with the Luau command line tool and against the message strings in Roblox Studio itself on 23 October 2026. A type check catches misspelt APIs and wrong types, not game logic, so playtest in Studio before you publish.