I somewhat disagree. Even if you don't use channels as iterators/generators (which many folks do), it's not hard to end up with a goroutine blocked on a channel that'll never be closed/written to, and this situation (like memory leaks) can result from changes elsewhere in the program or branches not normally taken.
A goroutine count doesn't seem like it'd be useful for diagnosing this in a non-trivial program. The runtime could probably detect if there are goroutines blocked on channels that no other goroutine has access to, and that'd be quite helpful for debugging, but as of now it doesn't. Even if it did, it couldn't catch all goroutine leaks.
>>A goroutine count doesn't seem like it'd be useful for diagnosing this in a non-trivial program.
Sure it is, if you are leaking goroutines you will see an every increasing count, even when your app is idle if the count doesn't return to the proper baseline then you know you have a problem.
If you start a goroutine should should have a plan for terminating it. If you don't have a natural way like the life cycle of handling a request then you need to use channels (defer/close are your friends), waitgroups, condition vars etc. I work on some fairly large Go applications and this hasn't been a pain point.