In short
When a server closes, Roblox runs every function bound with game:BindToClose and waits for them, but only for about 30 seconds. When that deadline passes, any script thread that is still waiting (on a data store call, a task.wait, a loop) is not resumed, and Output prints this line. In practice it nearly always means the shutdown save took too long: players were saved one after another, a save was retried with long waits, or the function waited on something that never came.
- Save every player at the same time, not one after another, and wait until all of them finish.
- Do not put long waits or endless loops in
BindToClose. - Save on
PlayerRemovingand on an autosave timer too, so the shutdown save is a safety net and not the only save.
What the message means
Not running script because past shutdown deadline
Other forms of the same message:
Not running script because past shutdown deadline in waitForUserInteraction
It is not a syntax or logic error in one line, so Output usually shows no script name. It reports that the server stopped some work because time was up. Whatever that work was, often the last saves, did not happen.
You see it most in Studio when you press Stop: the test server shuts down the same way, and Studio can sit frozen for up to 30 seconds while a slow BindToClose runs before it prints this.
Causes and fixes
Three things cause this error in practice. Each one below has the smallest code that triggers it, then the fix.
- Players are saved one after another
- Retries or waits that add up past the deadline
- Pressing Stop in Studio with a slow shutdown save
Players are saved one after another
Each SetAsync or UpdateAsync waits for Roblox's servers. With a full server, saving one player at a time adds those waits up, and the last players are still in the queue when the 30 seconds are over.
local DataStoreService = game:GetService("DataStoreService")
local Players = game:GetService("Players")
local store = DataStoreService:GetDataStore("PlayerData_v1")
game:BindToClose(function()
for _, player in Players:GetPlayers() do
-- one save at a time: a full server runs out of time
store:SetAsync(tostring(player.UserId), { coins = player:GetAttribute("Coins") })
task.wait(2)
end
end)
Start every save at once with task.spawn, count them, and wait until the count is back to zero. Wrap each save in pcall so one failure does not stop the others.
local DataStoreService = game:GetService("DataStoreService")
local Players = game:GetService("Players")
local store = DataStoreService:GetDataStore("PlayerData_v1")
local function save(player: Player)
local ok, err = pcall(function()
store:SetAsync(tostring(player.UserId), { coins = player:GetAttribute("Coins") or 0 })
end)
if not ok then
warn("[SaveData] could not save", player.Name, err)
end
end
Players.PlayerRemoving:Connect(save)
game:BindToClose(function()
local running = 0
for _, player in Players:GetPlayers() do
running += 1
task.spawn(function()
save(player)
running -= 1
end)
end
-- wait for every save to finish, well inside the 30 seconds
while running > 0 do
task.wait()
end
end)
The DataStore tutorial builds a full save module with session locking, autosave and this shutdown save.
Retries or waits that add up past the deadline
A retry loop that waits 5 or 10 seconds between attempts is fine while the game runs, but in BindToClose two or three retries are enough to pass 30 seconds. A fixed task.wait(30) "to give saves time" passes it on its own.
local DataStoreService = game:GetService("DataStoreService")
local Players = game:GetService("Players")
local store = DataStoreService:GetDataStore("PlayerData_v1")
game:BindToClose(function()
for _, player in Players:GetPlayers() do
local saved = false
while not saved do
saved = pcall(function()
store:SetAsync(tostring(player.UserId), player:GetAttribute("Coins"))
end)
if not saved then
task.wait(10) -- three failures and the deadline is gone
end
end
end
task.wait(30) -- a fixed wait passes the deadline by itself
end)
Give shutdown saves a small number of quick retries, and never a fixed long wait. Data that could not be saved is better logged with warn than waited on until the server kills the thread.
local DataStoreService = game:GetService("DataStoreService")
local Players = game:GetService("Players")
local store = DataStoreService:GetDataStore("PlayerData_v1")
local MAX_TRIES = 3
local function saveWithRetry(player: Player)
for attempt = 1, MAX_TRIES do
local ok = pcall(function()
store:SetAsync(tostring(player.UserId), player:GetAttribute("Coins") or 0)
end)
if ok then
return
end
task.wait(attempt) -- 1 then 2 seconds
end
warn("[SaveData] gave up saving", player.Name)
end
game:BindToClose(function()
local running = 0
for _, player in Players:GetPlayers() do
running += 1
task.spawn(function()
saveWithRetry(player)
running -= 1
end)
end
while running > 0 do
task.wait()
end
end)
Pressing Stop in Studio with a slow shutdown save
In a Studio playtest, Stop closes the test server and runs BindToClose. If Studio API access is off, or saves are slow, the save waits until the deadline and Studio freezes for a while before printing the message. Some developers skip the shutdown save in Studio with RunService:IsStudio() so that Stop is instant.
local DataStoreService = game:GetService("DataStoreService")
local store = DataStoreService:GetDataStore("PlayerData_v1")
game:BindToClose(function()
-- waits on a save that cannot finish while the test server stops
repeat
task.wait(1)
until pcall(function()
store:SetAsync("lastShutdown", os.time())
end)
end)
Turn on Enable Studio Access to API Services (Game Settings, Security) if you want saves to work in Studio, and keep the shutdown save short. If you skip it in Studio, remember that data then only saves on PlayerRemoving during tests.
local DataStoreService = game:GetService("DataStoreService")
local RunService = game:GetService("RunService")
local store = DataStoreService:GetDataStore("PlayerData_v1")
game:BindToClose(function()
if RunService:IsStudio() then
return -- Stop stays instant in Studio; live servers still save
end
local ok, err = pcall(function()
store:SetAsync("lastShutdown", os.time())
end)
if not ok then
warn("[SaveData] shutdown save failed:", err)
end
end)
Data store calls in Studio need Studio API access: see Studio API access is not enabled (DataStore 403).
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
- Search your scripts for
BindToClosewith Ctrl+Shift+F (Find All). Every function bound with it shares the same 30 seconds. - Read each one for loops over players that save one by one,
task.waitcalls and retry loops. - To time it, add
local started = os.clock()at the top of the function andprint("shutdown took", os.clock() - started)at the end, then press Stop.
Questions
How long does BindToClose get?
About 30 seconds for all bound functions together, per the BindToClose reference. After that the server closes whether or not they finished.
Does this mean player data was lost?
Possibly. Whatever was still waiting when the deadline passed did not run. If you also save on PlayerRemoving and on an autosave timer, the loss is at most the last few minutes.
Why does Studio freeze when I press Stop?
Studio runs your BindToClose functions when the test server stops and waits for them, up to the deadline. A slow or stuck shutdown save is what you are waiting on.
Should I skip BindToClose in Studio?
It is a common choice to keep Stop instant, and live servers still save. The trade-off is that shutdown saves are never tested in Studio, so test them in a live server too.
Can RoCode fix it?
Yes. Paste the line into RoCode. It finds every BindToClose in your open place and rewrites the shutdown save to run in parallel within the time limit.
Sources and further reading
- Roblox Creator Docs: DataModel:BindToClose. the 30 second limit and when it runs
- Roblox Creator Docs: Data stores best practices
- Roblox Creator Docs: RunService:IsStudio
- Roblox Developer Forum: "Not running script because past shutdown deadline" when using DataStore
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 and fails only when it runs. The message wording was checked against the message strings in Roblox Studio itself (macOS build installed 2 November 2026) and the DataModel:BindToClose reference on 5 November 2026. A type check catches misspelt APIs and wrong types, not game logic, so playtest in Studio before you publish.