Grab System has a bug

External Media

i encountered a bug when testing a grab system i “made” (i didn’t exacty make it myself, i just modified the script a little bit from the following post: Dragging objects with the mouse - Resources / Community Tutorials - Developer Forum | Roblox ). So whenever i grab an item/part, and i tab out and release my mouse, the part doesn’t just drop normally and returns the following error:
image

here’s the module script:

local module = {}

local player = game.Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local camera = workspace.CurrentCamera
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local TS = game:GetService("TweenService")
local RunService = game:GetService("RunService")
local UIS = game:GetService("UserInputService")
local CAS = game:GetService("ContextActionService")

local mouse = require(script.MouseModule):GetMouse() 

local HoldGrip = script.HoldGrip 
local attachment = Instance.new("Attachment")
local weld = Instance.new("WeldConstraint")
local SetNetworkOwner = ReplicatedStorage.Events:WaitForChild("SetNetworkOwner")
local GetNetworkOwner = ReplicatedStorage.Events:WaitForChild("GetNetworkOwner")
local ArmControl = ReplicatedStorage.Events:WaitForChild("IKControl")

local ChangeMouse = ReplicatedStorage.Events:WaitForChild("ChangeMouse")

local holdGrip
local target 
local hit
local oldOrientation, newOrientation = nil, CFrame.new()
local beganConnection, endConnection, draggingConnection

local function RayCast(distance, ignore)
	local PARAMS = RaycastParams.new()
	PARAMS.FilterType = Enum.RaycastFilterType.Exclude
	PARAMS.FilterDescendantsInstances = {character, unpack(ignore or {})}
	PARAMS.IgnoreWater = false

	return workspace:Raycast(character.Head.Position, ((mouse.Hit.Position - character.Head.Position).Unit * distance), PARAMS)
end

local function cleanup(distance)
	if target and not target.Anchored and target:HasTag("dragObject") then
		print("Cleaning up target:", target)
		local highlight = target:FindFirstChild("HL")
		if highlight then
			game:GetService("Debris"):AddItem(highlight, 0)
		else
			print("no highlight")
		end
		
		ChangeMouse:Fire(false)
		ArmControl:FireServer(false)
		
		player:GetMouse().Icon = ""
		
		local target_ = target
		target = nil
		hit = nil
		newOrientation = CFrame.new()
		if draggingConnection then
			draggingConnection:Disconnect()
		end
		oldOrientation = nil
		if holdGrip then
			holdGrip:Destroy()
		end
		holdGrip = nil
		if workspace.Terrain:FindFirstChild("DragAttachment") then
			workspace.Terrain.DragAttachment:Destroy()
		end
		if distance then
			local bindable = Instance.new("BindableEvent")
			coroutine.wrap(function() while true do
					RunService.RenderStepped:Wait()
					if (target_.Position - character.Head.Position).Magnitude > distance + 20 then
						bindable:Fire()
						break
					end
				end
			end)()
			bindable.Event:Wait()

			SetNetworkOwner:FireServer(target_, false) 
		end
	end 
end

function module:Start(distance, maxDistance, ignore, MaxForce, Responsiveness) --distance: distance from head when dragging, maxDistance: max pick  
	beganConnection = UIS.InputBegan:Connect(function(input)
		if input.UserInputType == Enum.UserInputType.MouseButton1 and input.UserInputState == Enum.UserInputState.Begin and player.Character then
			target = mouse.Target
			hit = mouse.Hit
			if target and target:HasTag("dragObject") and not(target.Anchored) and (character.Head.Position - target.Position).Magnitude <= maxDistance then 
				local isOwner = GetNetworkOwner:InvokeServer(target)
				if isOwner then
					
					local oldOrientation = target.CFrame - target.CFrame.Position
					local result = RayCast(maxDistance, {holdGrip})
					holdGrip = HoldGrip:Clone()
					holdGrip.Position = result and result.Position or character.Head.Position + ((mouse.Hit.Position - character.Head.Position).Unit * maxDistance)
					holdGrip.Parent = workspace
					
					ArmControl:FireServer(true, target)
					SetNetworkOwner:FireServer(target, true)
					ChangeMouse:Fire(true)
					
					local highlight = Instance.new("Highlight")
					highlight.Name = "HL"
					highlight.FillTransparency = 1
					highlight.OutlineTransparency = 0
					highlight.Parent = target

					local weld1 = weld:Clone()
					weld1.Part0 = holdGrip
					weld1.Part1 = target
					weld1.Parent = holdGrip


					local attachment1 = attachment:Clone()
					local result = RayCast(maxDistance, {target.Parent or target, holdGrip})
					local cframe = CFrame.new(result and result.Position or character.Head.Position + ((mouse.Hit.Position - character.Head.Position).Unit * distance))
					attachment1.Name = "DragAttachment"
					attachment1.Parent = workspace.Terrain
					attachment1.WorldCFrame = cframe * CFrame.Angles(cframe:ToEulerAnglesXYZ()):Inverse() * CFrame.Angles(target.CFrame:ToEulerAnglesXYZ())
					
					local gripAlignOrientation = holdGrip.GripAlignOrientation
					gripAlignOrientation.Attachment1 = attachment1
					
					local gripAlignPosition = holdGrip.GripAlignPosition
					gripAlignPosition.Attachment1 = attachment1
					gripAlignPosition.MaxForce = MaxForce or 30000
					gripAlignPosition.Responsiveness = Responsiveness or 15
					
					draggingConnection = mouse.HitChanged:Connect(function()
						newOrientation = CFrame.new()
						local result = RayCast(distance, {target.Parent or target, holdGrip})
						local cframe = CFrame.new(result and result.Position or character.Head.Position + ((mouse.Hit.Position - character.Head.Position).Unit * distance))
						attachment1.WorldCFrame =  (cframe * CFrame.Angles(cframe:ToEulerAnglesXYZ()):Inverse()) * (attachment1.WorldCFrame - attachment1.WorldCFrame.Position) * newOrientation 
					end)

					local increment = math.rad(5)
					local dict = {W = CFrame.Angles(increment, 0, 0), A = CFrame.Angles(0, increment, 0), S = CFrame.Angles(-increment, 0, 0), D = CFrame.Angles(0, -increment, 0)}
					local latestOrientations = {}
					
				else
					if target:WaitForChild("HL") then
						game:GetService("Debris"):AddItem(target:WaitForChild("HL"),0)
					else
						return end
				end
			end
		end
	end)

	endConnection = UIS.InputEnded:Connect(function(input)
		if input.UserInputType == Enum.UserInputType.MouseButton1 and input.UserInputState == Enum.UserInputState.End then
			cleanup(distance)
		end
	end)
end

function module:Stop()
	beganConnection:Disconnect(); endConnection:Disconnect(); CAS:UnbindAction("rotateDragged")
	cleanup()
end



return module

i would really appreciate any help, thanks in advance.

(also if anyone wanted to know why i didn’t just use dragdetectors. I’ve tried using it but i just couldn’t get it to work, also i couldn’t find any tutorials using dragdetectors related to this that could help me, and im not exactly the best at scripting soo, yeah.)