← Blog

Engineering · Chapter 7 of 16·2 min read

The Bug That Could Freeze the Whole App

Giving Nia the ability to write its own tools was the easy part. Making sure a bad one couldn't take down everyone using Nia at the same time took one very long night.

Listen to this story

0:00
Nia

Letting the AI build its own tools

Somewhere in Nia's toolset is one that lets it write a new tool for itself — real code, compiled and registered on the spot, when nothing already available does the job. It's a small feature to describe and a genuinely hard one to make safe, because the thing running that code is the same process everyone else's conversations are running through at the same time.

A hang that didn't make sense

During testing, a background task started hanging — not crashing, not erroring, just never finishing. The first suspect was the database: maybe too many things were trying to write at once. That theory got tested directly, empirically, before anyone touched a line of code — fifteen concurrent writes against a copy of the real database, all completed in about a second. Not the database.

The real cause

The actual answer was worse than a slow query: the newly-written tool's code was running directly on the same single thread everything else in the process depends on, no isolation at all. A tool whose generated code happened to contain a busy loop didn't just hang its own request — it froze the entire event loop, for the whole duration of that loop, for every single person whose request happened to be in flight on that same process at the same time.

One bad tool, written once, could stall everyone's conversation at once — not just its own.

Real isolation, verified live

The fix moved that generated code off the main thread entirely, into its own isolated worker with a hard five-second timeout — a runaway gets force-terminated rather than ever getting the chance to block anything else. Verified directly: an eight-second busy-wait tool request was rejected cleanly on schedule, the rest of the interface stayed fully responsive the whole time, and a normal tool created immediately afterward worked exactly as expected.

Then we found the same hole twice more

The same self-tool-writing feature existed in two other apps in the codebase, built the same way, with the exact same vulnerable pattern. Both got the identical fix, the same night, before moving on to anything else.

The scarier gap, closed last

The isolation fix alone left something uncomfortable true for a little while longer: right up until that same night, a freshly written tool could register itself and start running with no approval step at all — the only gate was whether the code compiled. The last commit before anyone went to sleep added a real confirmation step, the same pattern already required for every other genuinely risky action Nia can take: see what it wants to create, and say yes first.

Three real problems, found and closed in one sitting, in the order that made each one visible only once the last one was fixed.