What do you mean? This is exactly how hash verification is supposed to work. You either supply the correct hash or the verification fails, telling you the actual and expected hashes. Works the same way on any package manager that verifies its sources.
Oh, shades of my favorite bug ever, doing commercial product QA two decades ago.
The product had an external license file you'd need to drop alongside, and on boot if your licence key didn't match for your name + connection settings, the retail build would spit out both the key in the file, and the expected correct key for your settings.
It was not a priority fix for them, either. At least this one is merely informational, and not a potential gate on revenue.
In this case it is intentional and basically became a feature to the point that probably majority uses.
The hash requirement is kind of a chicken & egg problem, because to fetch a file you need the hash, and to get the hash you need to fetch the file. So this gives a way to escape it.
There's also the "proper way" to use the prefetch command (I personally like the nix-universal-prefetch) which basically fetches file to the cache and outputs the hash, but in that case it is one extra command which you need to figure arguments for, so the former method is just faster.
It's content addressable. If you use the old hash, it will just use the "old" contents happily (unless they don't exist). So you have to alter it slightly to get a "cache miss" to see what should have been produced.
This can be address by adding the version to the dependencies store path. This has been done for rust builds, not sure about go.
Are you kidding me?