Sum types are still a poor error handling strategy compared to exceptions, which actually implement the most common error handling pattern automatically for you (add context and bubble up). Having the language treat errors as regular values fails to separate these fundamentally different paths through the code. It also makes the programmer re-implement the same code pattern over and over again.
This cost may be necessary in manual memory management languages, where the vast majority of functions have to do some cleanup. There, having multiple exit points from a function through exceptions (or through early return statements) makes it harder to make sure all resources are properly cleaned up (especially when the cleanup of one resource can itself throw an error).
But in managed memory languages, there's just no reason to manually re-implement this pattern, either through Go style regular values or through sum types. And note that the Result monad is not a good substitute for exceptions, as it doesn't actually add the necessary context of what the code was doing when it hit an error case.
This cost may be necessary in manual memory management languages, where the vast majority of functions have to do some cleanup. There, having multiple exit points from a function through exceptions (or through early return statements) makes it harder to make sure all resources are properly cleaned up (especially when the cleanup of one resource can itself throw an error).
But in managed memory languages, there's just no reason to manually re-implement this pattern, either through Go style regular values or through sum types. And note that the Result monad is not a good substitute for exceptions, as it doesn't actually add the necessary context of what the code was doing when it hit an error case.