You can't generally cancel a running coroutine easily. You can of course do ====== rename runningCoro "" ====== But then: * the coroutine doesn't know it was cancelled(*), no error is raised inside it, it just ceases to exist * if the coroutine has scheduled itself as a callback like in e.g. ====== ::chan event $chan readable [list [info coroutine]] ====== just like say [coroutine::util gets] does, then that event will produce an error. Unfortunately I found no way to handle coroutine cancellation without resorting to callbacks. The good news is one can do ====== proc cleanup {args} {...} proc coro {} { ... trace add command [info coroutine] delete [list cleanup $arg1 $arg2] ... } ====== Which will allow it to e.g. unsubscribe from fileevent. Quite awkward: another proc has to be created and it also has too accept mostly args that [trace] passes to it in addition to any useful args we may pass from inside the coro.