What is the difference between cancel and close?

There’s task.cancel and coroutine.close. The latter is covered in a Luau Recap saying that it will mark a suspended coroutine as non-runnable and can be combined with defer to implement cancellation; the former is mentioned in a Release Note as “cancels a scheduled thread”.

Sounds like they aim for the same goal which is accept a thread to be cancelled. What, if any, is the difference between these two methods and where would I find it more appropriate to use one over the other or combine their use besides consistency and appearance?


There’s documentation in the beta docs: task.cancel and coroutine.close.

I wish they’d reference each other because you’re right, they are extremely similar and for the most part appear to be interchangeable.

The only difference that I can tell is that coroutine.close returns additional info if the thread is in an error state, while task.cancel always returns nil.

Maybe @tnavarts could add insight to the docs, they seem to have been active in the release notes thread.


The difference is really about context:

  • task.cancel is meant to be used with coroutines managed by the Roblox task scheduler such as those created by task.spawn and task.delay and is guaranteed to interact properly with the task scheduler.

  • coroutine.close is meant to be used with coroutines that you’re managing yourself so it comes with the additional return value that you may need to implement whatever custom thing you’re building with coroutines.

There may be a lot of overlap between them in practice because the Roblox task scheduler is based on coroutines, but the context is different enough that it makes sense for them to be separate.


  • If you created a coroutine with task.spawn use task.cancel on it.

  • If you created a coroutine with coroutine.create use coroutine.close on it.