Setting network ownership of a part in ChildAdded/DescendantAdded event falsely errors that it's anchored

Whenever :SetNetworkOwner is attempted to be ran on a part that’s just spawned in (i.e., in a ChildAdded/DescendantAdded etc. event), it falsely provides the following error message:

Network Ownership API cannot be called on Anchored parts or parts welded to Anchored parts.

This is not the case, as printing the object’s Anchored state, along with its connected parts (through :GetJoints() and :GetConnectedParts()) shows that it is not connected to any other object in workspace. Even cloning a simple Part into workspace reproduces this behavior.

Here is a simple place file that reproduces this behavior:
NetworkOwnershipBugRepro.rbxl (51.3 KB)

It clones a part into workspace with the script in ServerScriptService, and attempts to immediately set its network ownership in the ChildAdded event.

Expected behavior

I would expect :SetNetworkOwner to not error and work as expected, allowing me to set the part’s network ownership right after it’s been cloned into the workspace.

1 Like

For extra information, this only occurs with Immediate SignalBehavior, not Deferred.

Immediate (Default):

Deferred:
image

Code:

workspace.ChildAdded:Connect(function (c)
	if c:IsA("Part") and c.Name == "This" then
		print(c:GetNetworkOwner())
		c:SetNetworkOwner(game:GetService("Players"):GetPlayers()[1])
		print(c:GetNetworkOwner())
	end
end)

Repro:

  1. Create an unanchored part named This anywhere except Workspace.
  2. In test mode, switch to server view and drop the part into Workspace.
  3. Observe output.

Workarounds:

  1. Use Deferred SignalBehavior.
  2. Defer all network ownership-related calls in Immediate SignalBehavior[1].

[1]: Acceptable code with Immediate SignalBehavior:

workspace.ChildAdded:Connect(function (c)
	if c:IsA("Part") and c.Name == "This" then
		task.defer(function ()
			-- GetNetworkOwner also has to be deferred
			print(c:GetNetworkOwner())
			c:SetNetworkOwner(game:GetService("Players"):GetPlayers()[1])
			print(c:GetNetworkOwner())
		end)
	end
end)
3 Likes

So sorry for the late response! The engineers are aware of this one, and we’ll update you here when we have more info.

1 Like