D
P
0

Next.js

`next dev` Turbopack Crash `invariant expected layout router to be mounted` di Satu Mesin Saja? Junction `node_modules` Pelakunya

8 Juli 2026·4 menit baca
`next dev` Turbopack Crash `invariant expected layout router to be mounted` di Satu Mesin Saja? Junction `node_modules` Pelakunya

Saya lagi ngerjain fitur di sebuah aplikasi Next.js pakai dua worktree paralel di mesin Windows saya. Semuanya normal sampai saya jalankan next dev di worktree kedua, dan Turbopack langsung ambruk. Bukan warning, bukan halaman error yang rapi di browser, tapi crash beneran di terminal dengan pesan yang bikin saya berhenti:

invariant expected layout router to be mounted

Yang aneh: worktree pertama jalan mulus. Deploy production juga sehat, situs live-nya tidak ada masalah. next build lokal lolos tanpa keluhan. Hanya next dev di satu mesin, di satu worktree, yang meledak. Kombinasi seperti itu selalu menandakan bukan bug kode, tapi sesuatu di lingkungannya.

Gejalanya

Errornya datang dari internal layout-router App Router. Bacaannya seolah pohon router tidak pernah ter-mount, padahal saya tidak menyentuh satu pun file routing. Reflek pertama saya jelek: saya kira ada komponen yang salah pakai hook client di server, atau versi next yang tidak sinkron antar worktree. Jadi saya cek hal-hal yang biasa.

Saya bandingkan package.json dan lockfile antar worktree, identik. Saya cek versi next yang ke-resolve, sama persis. Saya hapus .next, restart, error-nya balik lagi. Saya bahkan buka kode yang sama di worktree pertama yang sehat, dan itu jalan tanpa masalah. File-nya identik. Yang berbeda cuma satu: bagaimana node_modules sampai ke worktree kedua.

Investigasi

Untuk hemat disk di worktree paralel, saya tidak npm install ulang di setiap folder. Saya bikin node_modules di worktree kedua sebagai directory junction Windows yang menunjuk ke node_modules di lokasi lain, di luar project root. Trik lama, biasanya tidak ada yang peduli, dan memang selama ini aman.

Saya konfirmasi dugaannya dengan melihat isi folder itu:

fsutil reparsepoint query node_modules

Benar, node_modules bukan folder asli, tapi reparse point yang di-resolve ke path di luar root project. Di titik ini pola gejalanya mulai masuk akal: Webpack tidak peduli, tapi Turbopack peduli. next build yang default masih pakai jalur kompilasi lama, jadi lolos. next dev yang sekarang default Turbopack, meledak.

Akar masalahnya

Turbopack me-resolve modul lewat path filesystem yang sebenarnya, bukan path logis yang kamu ketik. Waktu node_modules adalah junction, path yang ke-resolve "keluar" dari project root dan mendarat di lokasi asli junction. Buat Turbopack, itu artinya sebagian dependency tampak berada di luar batas project. React dan next bisa ke-resolve lewat dua identitas path yang berbeda, dan begitu App Router melihat dua salinan React yang secara path tidak sama, konteks router-nya pecah. Hasilnya persis invariant tadi: layout router seakan tidak pernah ter-mount, karena instance yang me-mount dan instance yang membaca konteks bukan React yang sama.

Jadi ini bukan bug kode dan bukan regresi Next.js. Ini murni artifak dari junction. Worktree pertama sehat karena node_modules-nya folder asli. Production sehat karena build-nya di lingkungan bersih tanpa junction. Cuma mesin saya, cuma worktree yang saya akal-akali disk-nya, yang kena.

Perbaikannya

Ada dua jalan, tergantung kamu mau pertahankan junction-nya atau tidak.

Kalau saya butuh dev jalan cepat dan tidak mau membongkar setup disk, saya paksa Turbopack mundur ke compiler Webpack. Webpack toleran terhadap junction karena resolve-nya tidak seketat itu soal path asli:

next dev --webpack

Dengan flag itu, dev server langsung normal lagi, error router-nya hilang total. Ini tambalan yang sah kalau kamu memang sengaja pakai junction dan sadar konsekuensinya.

Perbaikan yang benar-benar bersih adalah menghapus junction dan memasang node_modules lokal yang asli. Saya hapus reparse point-nya, lalu install ulang dari lockfile supaya deterministik:

rmdir node_modules
npm ci

Setelah install asli, node_modules jadi folder betulan di dalam project root, path resolve-nya tidak lagi keluar batas, dan next dev dengan Turbopack default jalan normal tanpa flag apa pun. Trade-off-nya cuma disk yang tidak lagi di-share antar worktree. Buat saya itu harga yang murah dibanding memburu invariant hantu setiap ganti worktree.

Checklist

Kalau next dev (Turbopack) crash dengan invariant expected layout router to be mounted tapi build dan production sehat, telusuri ini:

  • Cek apakah crash-nya cuma di satu mesin atau satu folder, bukan di CI atau deploy. Itu tanda kuat masalah lingkungan, bukan kode.
  • Verifikasi apakah node_modules folder asli atau junction dengan fsutil reparsepoint query node_modules. Kalau reparse point-nya menunjuk keluar project root, itu tersangka utama.
  • Tambal cepat dengan next dev --webpack untuk konfirmasi Turbopack pelakunya. Kalau Webpack jalan dan Turbopack tidak, dugaannya benar.
  • Perbaiki tuntas dengan rmdir node_modules lalu npm ci supaya ada node_modules lokal asli di dalam root.
  • Ingat: next build default bisa lolos walau next dev crash, karena keduanya bisa pakai jalur kompilasi berbeda. Jangan jadikan build hijau sebagai bukti dev pasti sehat.

Pelajaran saya di sini sederhana: Turbopack punya asumsi lebih ketat soal batas filesystem daripada Webpack. Junction yang selama bertahun-tahun aman buat menghemat disk bisa diam-diam melanggar asumsi itu, dan gejalanya menyamar jadi bug router yang sama sekali tidak nyambung dengan penyebab aslinya. Sejak itu, tiap kali sebuah error cuma muncul di satu mesin, pertanyaan pertama saya bukan lagi "kode mana yang salah", tapi "apa yang beda di filesystem saya".