Closing a task with Event:Wait() wrapped inside errors out

I’m making a game using highlights in which everyone is invisible until you make a noise. It’s a little hard to explain exactly how that works but i’ll just give the code in question that is breaking.

local SpawnedFunc
local SelfFlashTween

function HighlightFunctions:SelfFlash(VectorHighlight, FlashLength, DecayLength, OutlineTransparency, OutlineColor, FillTransparency, FillColor)
	if SpawnedFunc then
		task.cancel(SpawnedFunc)
	end
	if SelfFlashTween then
		SelfFlashTween:Cancel()
	end
	
	SpawnedFunc = task.spawn(function ()	
		local self = VectorHighlight
		
		local FlashTweenInfo = TweenInfo.new(DecayLength or 1, Enum.EasingStyle.Linear, Enum.EasingDirection.Out)
		self.FillColor = FillColor or self.FillColor
		self.FillTransparency = FillTransparency or 0
		self.OutlineColor = OutlineColor or self.OutlineColor
		self.OutlineTransparency = OutlineTransparency or 1
		task.wait(FlashLength or 0)
		
		SelfFlashTween = TweenService:Create(self, FlashTweenInfo, {FillTransparency = 1, OutlineTransparency = 0, OutlineColor = Color3.fromRGB(0,255,0)})
		SelfFlashTween:Play()
		SelfFlashTween.Completed:Wait()
		SelfFlashTween = nil
	end)
end

The reason I have this wrapped in task.spawn is because I want to reset the flash if its already started.
The easiest way to do that is to just cancel the task and start a new one. Right?
Well, yes. But although this works just fine, it produces the following error if I try to close the task while its waiting at SelfFlashTween.Completed:Wait()

image

I think this is a little weird as the state should be suspended while waiting, not dead.

I’ve tried putting this inside of a pcall() with no luck. It still prints out the same error.
Is there any way to silence this? Or is this some weird edge case where I’m using coroutines in an unintended manner and I shouldn’t be doing this at all.

I don’t think there’s any error in your code. This post also ran into a similar problem. As from the post, I think checks should be made on the variables SpawnedFunc and SelfFlashTween (such as checking if it’s Nil, type of value, etc.)

I already have checks for if they are nil or not.
if SpawnedFunc then works exactly the same as if SpawnedFunc ~= nil then and shouldn’t change anything.
Either way I tried putting that and… nope, as expected.

All I care about is silencing the error, and as long as this works as intended in game I don’t really care about the task’s feedback.

This is an issue on Roblox’s end, I made a feature request telling them to silent that useless error.

Here is the answer for you as well that someone left under my post:


EDIT: Not gonna lie, this concept of cancelling threads left more issues than expected (task.cancel and coroutine.close). They need to add a way to detect when a certain coroutine sets to a dead state with this addition for us to perform some cleaning, stopping other tasks, etc. Not that it just sets the coroutine to a dead state and done to avoid resuming…

1 Like

Temporarily, you can use this. Silence those errors.

Bummer, seems like this has been an issue for a while. I hope they get it fixed at some point because it is SUPER annoying.

This doesn’t work for the same reason that pcall() doesn’t work. The error isn’t coming from my script directly. (I think at least. I have no idea how roblox’s profiling works.)

image

I’ll just ignore it for now I guess. Kind of a shame that I can’t just remove it from my console.

it comes from your script “VectorHighlight” line 53

That was me testing ScriptContext. Even if I stopped it from printing, the error above that print would still happen, sooooo yeah. I still haven’t found a way to remove it and likely wont be able to.

I dont get why you dont just use coroutine.yield() with coroutines

I’m not using yield because there is no reason to yield it. I want to completely stop the thread and set it to dead, not suspend it for later, which is why i used task.cancel()

Either way I did try editing just this part of the script and it… doesn’t restart?

	if SpawnedFunc then
		coroutine.yield(SpawnedFunc)
	end
...
 SpawnedFunc = task.spawn(function ()
...
end)

I don’t think I understand coroutines enough to know why the effect doesn’t just restart itself when I yield and overwrite the old thread.

Here is what I got using coroutine.yield()

Versus the intended result with task.cancel()

Again, there is nothing wrong with my script (I think?) and i’m just looking to mute the error.