I too ended up replacing all channels with a mutex or two in a small web socket relay server in Go, and things became 10x easier to reason about.
I think part of the problem is the lack of usage/support for channels in the Go stdlib itself (seems that the stdlib authors also prefer mutexs). The other issue with sending a close msg on a channel to let the consumer know there will be no more messages, and that an error is thrown if you write to a closed channel.