There is no reason it has to be so boilerplate heavy, a lot of it can be fixed but someone has to put in the work. The only technical reason that could hold it back is compile times.
Zig has automatic error unions. No boilerplate at all, but not just a single "error" type. The only downside I see in zig errors is that they can't hold extra data.
It's a massive downside. When I was using the JSON parser I found it very annoying that it could only tell me the input JSON was invalid, not where in the input the problem was.
Of course there is a reason it is this way. In lower level languages, compilers need to know the type and size of the type at compile time. This holds true even for languages with looser typing like C.
You are not going to get strict types in a low level language and also get ergonomic errors. This is fundamentally not how compilers works.