I also maintain that requiring the developer to do manual error propagation to get errors from the point of failure to the point of reporting to the administrator or the operator (which is what happens to almost all errors, whether you are writing a command line tool, a graphical application, or a website) is "boilerplate". At the simplest, without changing the error model, littering the code with calls to try! that push the error upwards is automatable (and I have a friend working on a compiler plugin to accomplish exactly that).
An example: I like statically-typed languages, but as demonstrated by languages with type infererence, having to declare every type every time it is used is "boilerplate", especially if types are long and unwieldy. C++98 has typedef, which lets me take C++'s long and unwieldy type definitions and make them shorter. If you are used to typing them out manually, every single time, some might even claim this is "ergonomic". However, C++11's auto is much better, and as demonstrated by languages like OCaml and Haskell even that isn't as good as it can get. C and Go have long and unwieldy error propagation (checking flags and manually returning new ones). Rust provides macros and tooling for this that make it safer (no more "goto fail;" or "Rage Against the Cage" exploits) and easier (like typedef!), but that doesn't mean it isn't still "boilerplate".