astro dev がエラーも出さず死ぬ — Astro 7 の AI エージェント検出と ASTRO_DEV_BACKGROUND
Astro 7 のプロジェクトで astro dev を起動したら、こんな出力だけを残して死にました。
{"message":"Dev server process exited before becoming ready.","label":"SKIP_FORMAT","level":"error"}スタックトレースなし。原因の手がかりゼロ。しかも同じコマンドを人間がターミナルで叩くと普通に詳細なエラーが出る。何が起きているのか調べたら、Astro 7 の新機能「AI エージェント検出」が原因でした。
本記事では、この仕組みと、本当のエラーを表示させる方法(ASTRO_DEV_BACKGROUND=1)、あわせて踏んだ Node.js バージョンの罠をまとめます。
前提: Astro 7.0.7 で確認しています。Claude Code などの AI コーディングエージェント経由で astro dev を起動するケースが対象です。
Astro 7 は「エージェントに起動されたか」を検出する
Astro 7 の dev コマンドは、起動元が AI エージェントかどうかを am-i-vibing というパッケージで検出します。実装はこうなっています(astro/dist/cli/dev/index.js)。
import { detectAgenticEnvironment } from "am-i-vibing";
function isRunByAgent() {
try {
return detectAgenticEnvironment().type === "agent";
} catch {
return false;
}
}
// ...
const agentDetected = !process.env.ASTRO_DEV_BACKGROUND && isRunByAgent();
if (agentDetected) {
flags.json = true;
}
// ...
if (flags.background || agentDetected) {
// バックグラウンドモードへ
}エージェントと判定されると、自動的にバックグラウンドモード + JSON 出力に切り替わります。意図としては親切な機能です。エージェントが dev server をフォアグラウンドで起動してターミナルを掴んだまま固まる、という定番の事故を防いでくれます。
問題は失敗時です。バックグラウンドモードは dev server を切り離した子プロセスとして起動するため、子プロセスが起動中にクラッシュすると、その stderr はどこにも表示されず、親は冒頭の「exited before becoming ready」という一行だけを返します。起動失敗の原因(モジュール解決エラー、設定ミス、ポート衝突…)が全部この一行に丸められます。
解決: ASTRODEVBACKGROUND=1 で通常モードを強制する
検出ロジックを見ると、環境変数 ASTRO_DEV_BACKGROUND が設定されていればエージェント検出自体がスキップされます。
ASTRO_DEV_BACKGROUND=1 astro devこれで従来どおりフォアグラウンドで起動し、本当のクラッシュ理由がそのまま表示されます。エージェント環境で「astro dev が理由も言わず死ぬ」ときの調査は、まずこれです。
実際に隠れていたエラー: Node.js 22.15 未満
今回このモードで表面化したのは、これでした。
The requested module 'node:module' does not provide an export named 'registerHooks'Astro 7 / Vite 8 のツールチェーンは node:module の registerHooks を使っており、これは Node.js 22.15.0 で追加された API です(Node.js 22.15.0 リリースノートの SEMVER-MINOR: module: implement module.registerHooks())。環境の Node が 22.14 だったため、dev server が起動プロセスの途中で即死していました。Node を 22.15 以降に上げて解決です。
「Node 22 系なら大丈夫」という思い込みは通用しません。同じメジャーバージョン内のパッチ差で ESM の named export が存在しないという、なかなか気づきにくい死に方をします。
おまけ 1: バックグラウンドモードは専用サブコマンドで管理する
Astro 7 のバックグラウンドモードには管理用サブコマンドが用意されています。
astro dev status # 起動しているか確認
astro dev logs --follow # バックグラウンド dev server のログを見る
astro dev stop # 停止エージェント検出でバックグラウンド起動された server も、これらで面倒を見られます。「ログが見えない」ときは astro dev logs が正道です。
おまけ 2: pkill -f "astro dev" は自分を殺す
dev server を止めようとして pkill -f "astro dev" を実行すると、pkill を実行しているシェル自身のコマンドライン引数にも "astro dev" が含まれるため、pkill が自分自身(の属するプロセス)にマッチして即死します(exit code 144 など、何も殺せていないのに終了する)。
astro dev stop を使うのが一番ですが、ポートで殺す方法も確実です。
PIDS=$(lsof -ti:4321); [ -n "$PIDS" ] && kill $PIDSまとめ
- Astro 7 は
am-i-vibingで AI エージェント起動を検出し、自動でバックグラウンド + JSON モードに切り替える。起動失敗時のエラーが「exited before becoming ready」の一行に丸められる ASTRO_DEV_BACKGROUND=1を付けるとフォアグラウンド起動になり、本当のエラーが見える- Astro 7 / Vite 8 は
module.registerHooks(Node.js 22.15.0 で追加)を使う。Node 22 系でもパッチが古いと起動できない - バックグラウンド dev server の管理は
astro dev status/logs/stop。pkill -f "astro dev"は自分にマッチして死ぬ