ブログ一覧

astro dev がエラー表示なしで終了する原因(Astro 7)

更新: Web開発者向け

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 の CLI リファレンス)。

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" は実行したシェル自身にマッチして終了する

この記事をシェア