Real life programmers don't know the stack up and down and haven't read the documentation for the stuff they use. They will not have thought through every possible error case. Sucks, but that's real life. So any solution that depends on either of those will simply fail. So there's 2 ways to have parts of your program signal errors to other parts. The question that matters is what will mediocre programmers do ?
If you force em to give errors through return codes, they will flat-out ignore the errors. That means errors, and all meta-information about them (like which file it is that won't open, or which host doesn't respond, that sort of thing) disappears into a black hole. It MAY end up in some log file, or it may not. Crucially, sometimes it disappears into a logfile that is custom to the library being used (at least in C). Needless to say, you will have memory leaks when this happens, and you will have invalid state. It may also lead to crashes directly, if it doesn't it will lead to "delayed crashes" (like OOM), and all sorts of fun behavior (which is why some system engineers prefer direct crashes : it makes the point where the problem gets created easy to identify).
If you give them exceptions they will not handle the exceptions, nor will they get try ... finally correct. This will lead to memory leaks and inconsistent data. And it may lead to program crashes, BUT crucially it will preserve the error that was originally detected, and log it in the main program, making fixing the error critical.
Is this "deferred technical debt" ? I can understand your reasoning, but I think checked exceptions are a much, much better solution than return values.
What I find especially irritating is the moronic attitude that testing somehow makes up for not having static types. I have never seen a program that has half the tests any statically typed language automatically executes. Not even once.