People that use return codes simply don't check every possible value, otherwise they would see that it increases program length by at least 50% and makes the code unreadable. A common pattern in Go is this
if (err == MY_ERROR) { log my error; notify user; return MY_ENCAPSULATING_ERROR_CODE }
for high quality code this has to occur for every function call in the entire codebase. So you'll get huge functions which are mostly 'if' statements checking error codes, logging the results, and returning another error code that has to be checked again one step up the call stack.
moving from c++ to java 20 years ago it was clear that the c/c++ community didn't really know what they were doing in this regard. A lot of c/c++ dogma boilerplate code was holding it back. Too bad some of it made it into golang.