"trying to set locked parent!" warning message on tool pickup

I have this spawner that drops a clone of a spring-shaped tool which I can pick up by touching it with the player character. It can be activated (click while it is equipped) to spawn a GUI to attach it to one of the character’s legs.
The tool is destroyed inside of the player’s backpack with a script within the tool’s handle (meaning the script is technically destroying itself) after this is done.

When I spawn and pick up another of the same tool, a warning message that says “trying to set locked parent!” appears, but everything still seems to work properly.
Picking up a third tool after the second one shows no message.

Here’s a demonstration of what happens:

It seems that the warning only shows when I pick up a clone of the tool after a previous clone is destroyed while in the backpack.
It doesn’t tell me where the error message is being triggered in output.

The most similar forum post I could find about this issue is this one:

But it doesn’t result in anything helpful. Other forum posts also didn’t have any solutions, closest being to parent the tool to ReplicatedStorage and leave it unused, which isn’t ideal.

Feel free to ask for more information.

1 Like

Could you post some code snippets?

Only thing I picked up on was this

The tool is destroyed inside of the player’s backpack with a script within the tool’s handle (meaning the script is technically destroying itself) after this is done.

When a tool is equipped, it is moved from the backpack to the characters model, then when equipped, it is moved back to the backpack - I don’t think this idea would be the cause for any issues, but since I can’t see the code it’s hard to know.

I’ll show code snippets from ‘GiveScript’, which is a LocalScript inside the Tool.
It looks like this inside the player’s backpack:

The top of the script defines the handle object and the tool object:

local localPlayer = Players.LocalPlayer
local referenceDummy : Model = RS.ReferenceDummy
local spring = script.Parent -- Handle
local tool = spring.Parent -- Tool
local debounce = false

A couple of BindableEvents are fired to send information to and back from the GUI that shows when the tool is activated, but they shouldn’t affect anything about the Tool object.

Eventually, if the left leg is chosen, the script will run the attachLeftLeg() function, which welds a different spring model (not from the tool) to the player character:
(there is also another function to attach the right leg, but it is practically identical to this one)

local function attachLeftLeg()
	
	local character = localPlayer.Character
	local newWeld = referenceDummy.TallThickCoilMeshL:Clone()
	local weldPart = character:WaitForChild(newWeld.WeldPart.Value.Name) -- WeldPart being the objectvalue instance

	weld(newWeld, weldPart, newWeld.WeldPart.Value.CFrame:Inverse() * newWeld.CFrame)
	newWeld.Parent = character
	
	character.Humanoid.JumpPower += 20
	
	tool:Destroy()
end

Only the end of the function should affect the problem. The stuff before it just welds a part to the player character and changes JumpPower.
At the end it destroys the tool. It doesn’t set any references to nil because the LocalScript should destroy itself before it can.

1 Like

(This is all assuming the attachLeftLeg function is apart of the local script GiveScript)

I’m not 100% sure on what’s causing this, but I do have an idea. Now I don’t know how much you know, so I’ll be pretty verbose when explaining my though process - sorry if any of this seems patronising or obvious, I don’t intend for it to be.

1) When a player equips a tool, it moves from the backpack to the character model (and vice versa for unequipping)

UNEQUIPPED
image
EQUIPPED
image

So the tool’s parent property is being changed.

2) When an instance, such as a tool, is being destroyed, it’s parent property is locked. If you try and change the parent property whilst it is locked, you will get the “trying to set locked parent!” warning.

So AFTER you seemingly destroy the tool in the attach left leg function, something must be setting the parent property. You said this yourself:

. It doesn’t set any references to nil because the LocalScript should destroy itself before it can

So here’s what I think is happening, you’re destroying the tool via a local script - this means that the tool is only destroyed for that client.

Here I am holding a tool, I have a local script such that when I activate it it destroys itself.

Sure enough it’s destroyed, but this is from the client’s view.

Switching over to the server view, we see the player still holding a tool (just without the animation)

So by destroying the tool locally, the server still thinks the tool exists. You can see this on the hierarchy (server side):
image

Then, when you pick up the second tool, ROBLOX must parent that tool to your model (as stated in 1, tools which are equipped are children of the character model) So it moves the older (seemingly destroyed tool) over to the backpack.

As stated earlier, it does this by setting the parent property, however, the local script believes the tool is destroyed (because it is destroyed locally), so it’s under the impression that a locked property is being changed - which causes the warning to show up.

Sorry if any of that was poorly explained. Point is, I was able to get the same warning message with the following setup:

  • Tool with a local script, which when activated destroys itself (locally)
  • I then walked over to another tool which I picked up (similar to the video you showed)
  • The warning message showed up

If this is the cause of the issue (I’d suggest attaching the spring to your leg, then switching to the server view to see if your character is still holding the tool), you would need to destroy the tool on a server script instead. So use a remote event, which when fired tells the server to destroy the tool. Like I said earlier, I don’t know how much you know.

1 Like

That works!
Here’s the new attachLeftLeg() function:

local function attachLeftLeg()
	
	...
	
	destroyToolRemote:FireServer(tool)
	script.Enabled = false
end

The RemoteEvent fires the server and passes the tool instance to a Script named “DestroyTool” (inside ServerScriptService).
The tool is then destroyed:

if tool:IsDescendantOf(plr.Character) and tool:IsA("Tool") then
	tool:Destroy()
else
	warn("Invalid Tool or Player")
end

(I showed some code in case someone else wants to know how to tell the ServerScript where the tool is)

Thanks for the help! :grin:

1 Like