I’ve been fighting with an annoying issue for a while now. There’s a Storybook build which works in my local devshell but fails when building in a derivation. More annoyingly, the devshell is derived from the derivation, so the impedance mismatch is quite low ™.
Now, in this particular case, the toolchain wasn’t being of much help. Vite was telling me there was an unhandled exception somewhere, but for neither love nor money could I get it to tell me where!
Having admitted defeat, I was in the Clan Jitsi channel handing it over to hgl, a real frontend developer, when Qubasa piped up and said:
You know how to connect to the sandbox, right?Now, I’ve been using Nix for a few years. I’m no Mic92, but I’m no noob either. I like to think I can use the repl better than most, and I’m not too shabby when it comes to writing derivations.
The conversation continued…
[Me] You mean using `nix develop` to drop into the same environment within your current shell right? [Qubasa] No, I mean forcing your build to pause and connecting to the sandbox directly. [Me] You can do that?It turns out, you can!
It’s basically a container
Without getting into the details, at a high level you could say that the sandbox is basically a container. That is to say, it uses a lot of the same underlying technologies as containers. Which means you can use a lot of the same tools as you would with containers.
Now, in cooking the phrase “here’s something I made earlier” gets thrown around a lot. Within Nix, that tends to be “here’s something Mic92 made earlier”. So as you may have guessed, Mic92 has written something which can help us out.
Cntr is a nifty little tool for container debugging. And since we’ve learned that the sandbox is basically a container, we can use it to connect to the sandbox directly.
Let’s use hello as an example.
If you run nix build -f test.nix hello-sleep, you’ll see that the build pauses. In a separate terminal, run ps -aux | grep sleep and look for the nixbld* user running our sleep command:
With the process ID, we can now use cntr to connect to it:
Et, voilà! 🥳 🎉
There’s a better way
You might be thinking it’s a bit hacky dropping in a sleep command, and you’d be right. As it turns out, there’s a breakpoint hook which can be used to pause the build in the event of an error.
When you run nix build -f test.nix hello-breakpoint-hook, you’ll see that the build will pause and give you a handy command to run to connect to the sandbox:
As the output suggests, this is using cntr under the hood just like we were above.
Whilst you may consider breakpointHookCntr the OG breakpoint hook, there is a more recent and canonical one, breakpointHook, which ensures some env setup is performed correctly when you connect and gives you a fully qualified path to an attach script so you don’t have to ensure cntr is in your PATH:
Similary to breakpointHookCntr, you can run nix build -f test.nix hello-breakpoint-hook and you’ll see a command to connect to the sandbox:
TLDR
- Nix builds are basically containers 🐳,
- When something goes wrong, and you need to debug, breakpointHook is your friend 🫂.
.png)


