X is not a valid member of Y when it could call it 3 lines prior

I am making a tycoon game. I am trying to change the transparency and make a button collideable after the previous button is pressed.

Error:
Button is not a valid member of Model “ColorizerButton” - Server - Core:42
v.Button.Transparency = 0

I attempted alternative ways of writing this script, all end up not being able to find the child “Button” despite being able to 3 lines beforehand.

local tycoon = script.Parent.Parent

local mainItems = tycoon:FindFirstChild("MainItems")
local values = tycoon:FindFirstChild("Values")

mainItems.OwnerDoor.Door.Touched:Connect(function(hit)
	if values.OwnerValue.Value == nil then
		local player = game.Players:GetPlayerFromCharacter(hit.Parent)
		if player then
			if player:FindFirstChild("HasTycoon").Value == false then
				values.OwnerValue.Value = player
				mainItems.OwnerDoor.Title.SurfaceGui.TextLabel.Text = tostring(values.OwnerValue.Value).."'s Tycoon"
			end
		end
	end
end)

local buttons = tycoon:FindFirstChild("Buttons")
local purchasedItems = tycoon:FindFirstChild("PurchasedItems")

local objects = {}

if buttons then
	for i, v in pairs(buttons:GetChildren()) do
		spawn(function()
			if v:FindFirstChild("Button") then

				local newObject = purchasedItems:FindFirstChild(v.Object.Value)
				if newObject ~= nil then
					objects[newObject.Name] = newObject:Clone()
					newObject:Destroy()
				else
					v:Destroy()
				end

				if v:FindFirstChild("Dependency") then
					v.Button.Transparency = 1
					v.Button.CanCollide = false
					v.Button.BillboardGui.Enabled = false
					coroutine.resume(coroutine.create(function()
						if purchasedItems:WaitForChild(v.Dependency.Value) then
							v.Button.Transparency = 0
							v.Button.CanCollide = true
							v.Button.BillboardGui.Enabled = true
						end
					end))
				end

				v.Button.Touched:Connect(function(hit)
					local player = game.Players:GetPlayerFromCharacter(hit.Parent)
					if player then
						if values.OwnerValue.Value == player then
							if v.Button.CanCollide == true then
								if player:FindFirstChild("leaderstats").Cash.Value >= v.Price.Value then
									player.leaderstats.Cash.Value -= v.Price.Value
									objects[v.Object.Value].Parent = purchasedItems
									v:Destroy()
								end
							end
						end
					end
				end)
			end
		end)
	end
end

Its because in this block of code you are destroying v.

Then you create a new coroutine once you wait for child v.Dependency above.,
What you can do is put a if v.Button still exist after wait for child.

So for example lets say you create that coroutine and it takes 5 seconds to wait for v.Depedency.Value and within the 5 seconds at second 3 you touch the button, it will destroy v and can no longer access button child.

something like this

local tycoon = script.Parent.Parent

local mainItems = tycoon:FindFirstChild("MainItems")
local values = tycoon:FindFirstChild("Values")

mainItems.OwnerDoor.Door.Touched:Connect(function(hit)
	if values.OwnerValue.Value == nil then
		local player = game.Players:GetPlayerFromCharacter(hit.Parent)
		if player then
			if player:FindFirstChild("HasTycoon").Value == false then
				values.OwnerValue.Value = player
				mainItems.OwnerDoor.Title.SurfaceGui.TextLabel.Text = tostring(values.OwnerValue.Value).."'s Tycoon"
			end
		end
	end
end)

local buttons = tycoon:FindFirstChild("Buttons")
local purchasedItems = tycoon:FindFirstChild("PurchasedItems")

local objects = {}

if buttons then
	for i, v in pairs(buttons:GetChildren()) do
		spawn(function()
			if v:FindFirstChild("Button") then

				local newObject = purchasedItems:FindFirstChild(v.Object.Value)
				if newObject ~= nil then
					objects[newObject.Name] = newObject:Clone()
					newObject:Destroy()
				else
					v:Destroy()
				end

				if v:FindFirstChild("Dependency") then
					v.Button.Transparency = 1
					v.Button.CanCollide = false
					v.Button.BillboardGui.Enabled = false
					coroutine.resume(coroutine.create(function()
						if purchasedItems:WaitForChild(v.Dependency.Value)  then
							if not v or not v.Button then
								-- player most likely touched v.Button triggering the .Touched event
								return
							end
							v.Button.Transparency = 0
							v.Button.CanCollide = true
							v.Button.BillboardGui.Enabled = true
						end
					end))
				end

				v.Button.Touched:Connect(function(hit)
					local player = game.Players:GetPlayerFromCharacter(hit.Parent)
					if player then
						if values.OwnerValue.Value == player then
							if v.Button.CanCollide == true then
								if player:FindFirstChild("leaderstats").Cash.Value >= v.Price.Value then
									player.leaderstats.Cash.Value -= v.Price.Value
									objects[v.Object.Value].Parent = purchasedItems
									v:Destroy()
								end
							end
						end
					end
				end)
			end
		end)
	end
end

that is still producing the same error, this time on line 42:
if not v or not v.Button then

Button is not a valid member of Model “ColorizerButton” - Server - Core:42

if this helps, heres some screenshots of my explorer
Before Testing:
image

After Joining Game:
image

After Buying Dropper1 (First Button):
image

ah sorry change to

if not v or not v.Parent or not v.Button then

since there is still a variable refrence - v, v still exist in memory, but is no longer in game
When deleted the parent is set to nil so just add in the v.Parent check

The error is gone, but the ColorizerButton is not appearing now,