Hi. I’m trying to fix this mistake but I couldn’t until now. I was able to isolate the error to these two scripts:
-- Script
local ReplicatedSorage = game:GetService("ReplicatedStorage")
local sourceFolder = Instance.new("Folder", ReplicatedSorage)
sourceFolder.Name = "Source"
local part
while true do
for _ = 1, 10 do
part = Instance.new("Part", sourceFolder)
end
wait(5)
sourceFolder:ClearAllChildren()
end
-- LocalScript
local ReplicatedSorage = game:GetService("ReplicatedStorage")
local sourceFolder = ReplicatedSorage:WaitForChild("Source")
local targetFolder = Instance.new("Folder", workspace)
targetFolder.Name = "Target"
local onChildAdded = function (child)
child.Parent = targetFolder
end
sourceFolder.ChildAdded:Connect(onChildAdded)
In short, the server dynamically creates parts in replicatedstorage every so often. Then the client moves each part to workspace. The error is this:
06:42:42.850 - Something unexpectedly tried to set the parent of Part to Target while trying to set the parent of Part. Current parent is Source. (x10)
On the client side the parts don’t move to workspace.
I remember that some time ago I did something similar and it worked well.
I mean, when is it too fast to do something on the client? I understand that you have to wait for the parts to replicate but in this case childadded does that job.
This is how Roblox instances work at the moment. You can’t destroy/reparent parts instantly after they have been reparented and you will get that error message. You can go around it by waiting the smallest possible amount, which wait() will do, but the wait function will also wait to long (around 0.03 seconds which is longer than what you need to wait). This code should also go around your issue:
local onChildAdded = function (child)
spawn(function() child.Parent = targetFolder end)
end
For all other cases (even this one) I would recommend verifying that your use-case actually requires the behaviour you’re defining here.
It might be “better” than just doing wait(), but it’s still a time-based wait, while using spawn() ensures it gets executed as fast as possible while still giving the Roblox thread enough time to process the instance reparenting.
Putting a Wait method on a connection (RBXScriptSignal) like RenderStepped or Touched, it’ll make the thread yield until the event fires and returns its parameters /arguments. If you add a Wait method to a RenderStepped, it’ll make the script yield until the event is fired, so RenderStepped doesn’t always run at 60 Hz, – its frequency is dependent on your frame rate since it relies on the connection itself to fire, which has its frequency dependent on the machine’s frame rate
It doesn’t matter what you use, but I prefer this method.