Skip to content
Development

The logger that crashed trying to report its own crash

By Victor Da Luz
astrocloudflaredebuggingdev-logsite

I closed out the homepage i18n work with a knowledge-base note that basically said “npm run dev is broken here, use npm run preview instead.” That bugged me. I’d documented a symptom and a workaround, not a cause. So I opened a follow-up and actually went and read the code.

The error was process is not defined, thrown from inside Astro’s own logger while the logger was trying to report a completely different error. A crash reporting a crash. And it happened on every route - not just the page I’d just written - which was the tell that this had nothing to do with my Spanish translation work at all.

Turns out Astro is watching for coding agents

Astro 7 ships a package called am-i-vibing that detects whether it’s being run inside an AI coding agent. Read that twice - the build tool checks whether the thing invoking it is an agent. And in my setup, it usually is: an agent drives most of these dev sessions.

const agentDetected = !process.env.ASTRO_DEV_BACKGROUND && isRunByAgent();
if (agentDetected) {
  flags.json = true;
}
...
if (flags.background || agentDetected) {
  await background({ flags, logger });
}

When it detects an agent, it auto-enables JSON-structured logging and daemonizes the dev server into the background - which explains the odd “Stop: astro dev stop / Status: astro dev status / Logs: astro dev logs” message I’d been seeing and not questioning. It’s a thoughtful feature: agents don’t want a blocking foreground process, and structured logs are easier to parse than ANSI-colored terminal output. Astro built this for exactly the workflow I run.

The bug hiding inside the feature

The JSON logger’s write function does this, no guard rails:

write(event) {
  let dest = process.stderr;
  ...
  dest.write(JSON.stringify({ ... }));
}

That’s fine in a normal Node process. But @astrojs/cloudflare’s dev mode doesn’t render pages in Node - it spins up an actual workerd sandbox, the real Cloudflare Workers runtime, so that what you see locally matches production as closely as possible. That sandbox has no process global. It’s not Node. So the instant anything inside that sandbox needed to log an error, the JSON logger reached for process.stderr, found nothing, and threw - and that secondary failure is the only thing that ever reached my browser.

I still don’t know what the original error was. I know its replacement, though, and that was enough to work around it properly instead of guessing.

The fix

Setting ASTRO_DEV_BACKGROUND=1 before astro dev defeats the agent-detection check entirely - no JSON logger, no daemon, just the normal pretty-printed Node logger, which works fine because it only ever runs in the parent CLI process, never inside the workerd sandbox. One line in package.json:

- "dev": "astro dev",
+ "dev": "ASTRO_DEV_BACKGROUND=1 astro dev",

Confirmed by hammering /, /blog/, and /es/ repeatedly - clean 200s every time, where before the fix every single route 500’d consistently for the rest of that server’s life.

Lesson

“It works if I use the other command” is a workaround. It took maybe fifteen extra minutes to actually read astro/dist/cli/dev/index.js and logger/impls/json.js instead of stopping at the note I’d already half-written, and that’s the difference between “here’s a thing to try” and “here’s exactly what’s wrong and why.” The second one is the one that’s still true next time Astro ships a minor version.

Related reading