You could also consider moving the local script into a different parent like the playergui which might not cause it to be deleted and then you can detect when the tool is unequipped or deleted, then have the local script handle all the stuff it needs to do to cleanup, then delete itself.
You’ll have to use an external script for this. If Destroy is called on an instance, it will also subsequently be called on all descendants of the instance as well. Destroy effectively disconnects all connections, locks the object and parents it to nil for garbage collection. AncestryChanged is an RBXScriptSignal, so calling Destroy would of course also disconnect this.
You should probably rethink your model if this temporary script acts upon a permanent UI, such as having the UI update itself based on whether the tool exists or not. You can use bindables or modules to pass data. Or something. Depends on how you want to go about it.
The GUI is the interface for the tool, so when the tool leaves the GUI should too. I was trying to compensate for if the tool gets deleted while it’s in use, but this is an edge case and can be fixed by resetting, and the main reason a tool would get deleted while in use is if the player dies.
When a script gets destroyed, its thread doesn’t stop running, but as colbert said, the connections for and by that script are disconnected, which is why it didn’t work in this case.