How to extract signal from almost useless error message

At face value, and in isolation, this is very clear. Now:

   35|         packages.abracadabra = pkgs.stdenv.mkDerivation {
   36|           name = "abracadabra";
     >           ^
   37|           src = self;

cannot coerce a function to a string
(use '--show-trace' to show detailed location information)

If a tool tells you that a function cannot be coerced to a string and points at line 36, the most natural question is: OK, where is the function on line 36?.

Erm, the part of the error messate pointing to line 36 is lost (and I hope that --show-trace would show you which file it is in)

In fact, it turned out that the function is on line 98. There is no way I would have understood this were it not for the fact that I had just changed line 98. Before this incident, this same error message in different contexts had simply caused me to grind to a halt on multiple occasions.

Note that this is yet another context. The first case was Nix relaying an error from the build scripts. The second was Nix reporting an error during build (hash mismsatch for fixed-output derivation). Now this is about Nix evaluation phase. Yes, Nix evaluation errors indeed take much more getting used to to read (and «fluently» might require waiting for a change in Nix, not in you). Yes, they are often harder to read than they should be. Yes, there is some work ongoing and some cases have been improved but far from all. I guess error "value is a list while a set was expected" is too vague · Issue #963 · NixOS/nix · GitHub is close to that specific problem… There is nix-errors-enhancement - error format demo by bburdette · Pull Request #3466 · NixOS/nix · GitHub (and related work) and I have no idea if Add a flag to start the REPL on evaluation errors by edolstra · Pull Request #3901 · NixOS/nix · GitHub ever gets merged but it would be useful.

But yes, debugging Nix evaluation errors is hard (one gets better of it with time — but this is not a pleasant time for sute) and I hope it will become easier some day.

With this experience under my belt, my instinct will be to ignore the line where the message points, and look somewhere else. Give me a week of Nixing, and I’ll be able to recall another dozen situations where Nix has taught me to ignore what the message ostensibly says.

I would say that with any tool the first thing I wonder about error messages is whether they are weirdly distinct types (like syntax errors and linker errors, which both can happen when running gcc), and which parts I can trust in which case. (On Nix-based systems linker messages in particular might need some interpretation when one does things interactively…)

The deeper you are in the stack of confusion, the more likely it is that cold, calculating, calm and analytical reading of the error message is replaced by heuristics.

I guess way before I came to Nix, a curl error message already was a pattern I would recognise before thinking what this error message does in the middle of my terminal emulator window. So my basic heuristics independent of Nix already work for build failures (which were the beginning of the discussion). Learning heuristics for reading evaluation traces was less pleasant…

Perhaps I spent too much time hanging out with early C++ in my youth, where about 80% of error message interpretation was of the form “30 screenfuls of line noise which resemble cat vomit usually mean that you’re trying to compile C++ with a C compiler, but if it looks a bit more like weasel vomit then you’ve probably written using namespace std; and one of those names clashes with one of your own; but this here looks like alpaca vomit, so you probably forgot the semicolon after class {...} … in a file that doesn’t even get mentioned in this error message.” This experience may have caused a form of brain damage which gives me a tendency to reach for heuristics too quickly and stick with them for too long, and Nix is certainly bringing this tendency to the fore.

You are discussing triaging the rough shape of the failure. Yes, that’s definitely needed with Nix because failures come from vastly different contexts.

Perhaps my problem is that my comfort zone is inside programming languages, and with Nix I’m mostly dealing with package management and system configuration and the like … nasty, dirty problems whose existence my programming language purist side would like to ignore.

Annoyingly, programming part of Nix actually has worse error messages than the system administration part (i.e. evaluation has worse messages than builds)… On the building side, though, there is indeed an expectation that you know how a working build would look like and how failures from the build could look like (if you are writing an expression and not just using the existing ones)

2 Likes