Masalah Instalasi yang Umum
Dokumen ini menghubungkan gejala yang muncul setelah instalasi dengan penyebab sebenarnya dan perbaikan paling kecil yang diperlukan. Hampir semua kasus di sini adalah kegagalan yang bersifat silent atau menghasilkan pesan yang menunjuk ke hal lain — misalnya 404 tanpa exception, build error tentang module specifier, atau screen yang sebenarnya HTTP 200 tetapi dirender di dalam shell aplikasi yang salah.
Mulai dari Sini
php artisan panel:install --no-panel --no-user --no-interaction # re-runs every check; publishes only what is absent
php artisan route:list --name=panel. # did the routes register at all
php artisan panel:clear # is a stale manifest hiding something
tail -f storage/logs/laravel.log # the panel logs several of these2
3
4
Command pertama berfungsi sebagai diagnostic utama. Dengan --no-panel --no-user, installer hanya mempublish bagian yang belum ada, kemudian memeriksa ulang Inertia, Vite, npm dependency, layout assignment, serta host modules, lalu mencetak seluruh temuan.
| Gejala | Bagian |
|---|---|
| URL Panel menghasilkan 404 | Tidak ada yang menjawab pada path Panel |
| 403 setelah sign-in | 403 dari Panel itu sendiri |
| Panel dirender di dalam shell aplikasi | Layout tertimpa |
Failed to resolve import saat build | Build tidak dapat me-resolve module |
| 500 pada URL Panel pertama | Tidak ada Inertia root view atau middleware |
| Sign-in tetap masuk ke starter kit dashboard | Home redirect |
| Guest diarahkan ke login yang salah | Guest redirect |
| Resource tidak muncul di sidebar | Resource tidak masuk navigation |
| Resource yang baru ditambahkan tidak terlihat | Panel manifest stale |
| Icon tidak muncul | Icon tidak tergambar |
| Widget atau Column kosong | Component tidak ada di registry |
vendor:publish tidak menghasilkan apa pun | Publish tidak melakukan apa pun |
panel:assets melaporkan CONFLICT | Asset conflict |
panel:user gagal | panel:user menolak |
Echo has not been configured | Broadcasting tanpa broadcaster |
| Composer tidak mau memasang package | Composer menolak |
Tidak Ada yang Menjawab pada Path Panel
Gejala. /admin menghasilkan 404. Provider file sudah ada. make:panel melaporkan sukses.
Penyebab. Panel menggunakan explicit registration, bukan discovery. Provider yang tidak tercantum pada config/panda-panel.php tidak diregistrasikan, tidak memiliki route group, dan karena itu tidak memiliki URL. Ini adalah penyebab paling umum dari kasus "sudah diinstal tetapi tidak bekerja".
// config/panda-panel.php
'panels' => [
App\Panels\Admin\AdminPanelProvider::class,
],2
3
4
Konfirmasi.
php artisan route:list --name=panel.Hasil kosong berarti tidak ada Panel yang terdaftar. Tiga penyebab lain juga dapat menghasilkan output kosong yang sama:
| Check | |
|---|---|
| Config belum pernah dipublish sehingga installer tidak memiliki file yang dapat diedit | ls config/panda-panel.php |
Array panels sudah direstrukturisasi sehingga PanelRegistrar membiarkannya dan melaporkan outstanding work | Cari key panels yang dibangun dari variable |
register_routes bernilai false | config('panda-panel.register_routes') |
Provider class yang disebut di config tetapi class-nya sudah tidak ada akan dilewati, bukan membuat aplikasi fatal. Fatal saat boot akan menjatuhkan seluruh route, termasuk route yang seharusnya membantu menunjukkan error. Karena itu typo pada class name dapat terlihat persis seperti kasus ini. Jalankan php artisan panel:cache untuk melihat class yang benar-benar ditemukan.
403 dari Panel Itu Sendiri
Gejala. User sudah sign-in, tetapi setiap URL Panel menghasilkan 403.
Penyebab. Panel menanyakan dua rule independen dan keduanya harus sama-sama mengizinkan:
// the panel's own rule, in its provider
->canAccess(static fn (?Authenticatable $user): bool => $user?->is_admin === true)
// a rule about the account, on the user model
public function canAccessPanel(PandaPanel\Core\Panel $panel): bool;2
3
4
5
User yang sudah sign-in tetapi ditolak akan mendapatkan 403, bukan redirect. Menyembunyikan navigation bukan access control.
Konfirmasi.
php artisan tinkeruse PandaPanel\Core\PanelManager;
$user = App\Models\User::query()->where('email', 'ada@example.com')->first();
app(PanelManager::class)->get('admin')->isAccessibleTo($user); // false2
3
4
5
panel:user --panel=admin menanyakan rule yang sama saat account dibuat dan menyebutkan rule mana yang menjawab tidak.
Privilege flag biasanya sengaja tidak mass-assignable, karena is_admin yang berada di $fillable berarti privilege dapat diberikan melalui crafted form POST. Karena itu pemberian privilege dilakukan sebagai write eksplisit:
$user->forceFill(['is_admin' => true])->save();Bukan kasus ini. Jika hanya satu Resource yang menghasilkan 403 sementara Panel lainnya dapat diakses, masalahnya adalah policy/authorization Resource, bukan Panel access. Lihat Resource tidak masuk navigation.
Layout Tertimpa
Gejala. Page Panel menghasilkan HTTP 200 tetapi dirender di dalam sidebar aplikasi sendiri, sementara navigation Panel tidak muncul. Tidak ada log error.
Penyebab. Setiap Page Panel mendeklarasikan layout sendiri melalui defineOptions({ layout: PanelLayout }). Assignment unconditional di Inertia resolver mengganti layout tersebut setelah Page memilihnya:
page.default.layout = AppLayout; // wrong
page.default.layout ??= AppLayout; // right
page.default.layout ||= AppLayout; // also right2
3
Konfirmasi.
PandaPanel\Support\Installer\FrontendRequirements::layoutOverrides();
// [['file' => 'resources/js/app.ts', 'line' => 12, 'code' => 'page.default.layout = AppLayout;']]2
panel:install melaporkan file, line number, dan replacement yang benar. Check ini dilakukan otomatis karena inilah salah satu integration seam yang tidak dapat diperbaiki package dari dalam dirinya sendiri.
Build Tidak Dapat Me-resolve Module
Gejala. npm run build gagal dengan Failed to resolve import "@/routes/login", atau error serupa untuk @/components/UserMenuContent, reka-ui, vue-sonner, dan module lainnya.
Penyebab. Ada dua kategori masalah yang menghasilkan pesan build hampir sama.
use PandaPanel\Support\Installer\FrontendRequirements;
FrontendRequirements::missingNpmPackages(); // a dependency your package.json does not declare
FrontendRequirements::missingHostModules(); // a module your application owns and does not have2
3
4
Perbaikan.
npm install @inertiajs/vue3@^3.0.0 reka-ui@^2.0.0 # whatever panel:install listed
php artisan wayfinder:generate # for every @/routes/* and @/actions/*
npm run build2
3
Daftar module yang hilang menunjukkan kategori masalah. Jika seluruh @/routes/* dan @/actions/* hilang, Wayfinder belum berjalan. Jika hanya beberapa component hilang, aplikasi kemungkinan bukan Laravel Vue starter kit dan file tersebut harus disediakan sendiri. Lihat Frontend requirements.
Tidak Ada Inertia Root View atau Middleware
Gejala. URL Panel pertama menghasilkan 500, biasanya berupa View [app] not found atau error Inertia lain.
Penyebab. Setiap screen Panel merupakan Inertia response. Dua file harus tersedia:
FrontendRequirements::missingInertia();
// ['an Inertia root view at resources/views/app.blade.php',
// "Inertia's middleware (php artisan inertia:middleware)"]2
3
Perbaikan.
php artisan inertia:middlewareLalu sediakan root view pada resources/views/app.blade.php. Aplikasi Blade-only tidak dapat langsung menjadi host untuk Panel; ini bukan feature flag yang dapat diaktifkan hanya melalui config.
Home Redirect dalam Dua Arah
Gejala A. Setelah sign-in user masih masuk ke placeholder /dashboard milik starter kit, bukan ke Panel.
Penyebab. home_redirect.enabled bernilai false, path dashboard tidak masuk list, atau signed-in user tidak diterima oleh Panel mana pun — pada kasus terakhir memang tidak ada tujuan redirect yang valid.
// config/panda-panel.php
'home_redirect' => [
'enabled' => true,
'paths' => ['dashboard'],
],2
3
4
5
Gejala B. /dashboard adalah screen penting milik aplikasi dan sekarang tidak dapat dibuka oleh signed-in user.
Perbaikan. Matikan home redirect. Route, nama route, dan pages/Dashboard.vue tidak pernah diubah; request hanya dijawab lebih awal oleh middleware web.
'home_redirect' => ['enabled' => false],Value paths menggunakan pattern Request::is(), sehingga 'reports/*' dapat menyerahkan satu section penuh. Path yang menjadi mount point Panel itu sendiri diabaikan, agar Panel pada /dashboard tidak melakukan redirect ke dirinya sendiri tanpa akhir. Guest, non-GET request, dan request JSON juga tidak diubah.
Guest Redirect
Gejala. Guest yang membuka URL Panel diarahkan ke Login Page aplikasi, bukan Login Page Panel, atau custom redirectGuestsTo() milik aplikasi berhenti berlaku.
Penyebab. Service provider meregistrasikan PandaPanel\Support\PanelLoginRedirect kecuali dimatikan melalui config. Rule tersebut merupakan strict superset dari default Laravel: request yang bukan Panel request atau Panel tanpa Login Page sendiri tetap diarahkan ke route('login'). Jadi yang benar-benar ditimpa hanya aplikasi yang sebelumnya sudah mendefinisikan custom redirect sendiri.
// config/panda-panel.php
'register_guest_redirect' => false,2
// bootstrap/app.php
use PandaPanel\Support\PanelLoginRedirect;
$middleware->redirectGuestsTo(
fn ($request) => PanelLoginRedirect::for($request) ?? route('welcome'),
);2
3
4
5
6
Panel hanya memiliki Login Page sendiri jika memanggil ->login(). Tanpa itu, ->auth() tetap melindungi Panel tetapi guest diarahkan ke Login Page milik aplikasi.
Resource Tidak Masuk Navigation
Gejala. Resource class ada, discovery menemukannya, tetapi Resource tidak muncul di sidebar. URL Resource menghasilkan 403.
Penyebab yang paling umum. Model belum memiliki policy. Gate::allows() menolak ketika policy tidak tersedia — behavior ini benar dan dari luar tidak dapat dibedakan dari policy yang memang mengevaluasi request lalu menjawab tidak. Karena itu Resource baru secara default menghasilkan 403 sampai policy dibuat. Ini adalah default yang disengaja: jauh lebih aman daripada Panel menampilkan seluruh record hanya karena developer belum menulis authorization rule.
Konfirmasi. Pada development Panel mencatat kondisi tersebut sekali per model:
[panel] ProductResource is not in the navigation because Product has no policy, so viewAny()
is denied by default. Create one with `php artisan make:policy ProductPolicy --model=Product` …2
Perbaikan.
php artisan make:policy ProductPolicy --model=ProductAtau jadikan seluruh kelas kesalahan tersebut loud daripada silent:
$panel->strictAuthorization();Dengan strict authorization, model tanpa policy — atau policy tanpa method untuk ability yang sedang diperiksa — melempar PandaPanel\Exceptions\PanelAuthorizationException daripada hanya terlihat sebagai deny yang valid.
Penyebab lain dengan gejala sama: Resource ditemukan oleh Panel berbeda, canViewAny() memang mengembalikan false, atau Panel manifest sudah stale.
Panel Manifest Stale
Gejala. Resource, Page, atau Widget yang baru ditambahkan tidak terlihat. Tidak ada route, navigation entry, maupun error.
Penyebab. panel:cache telah membuat manifest. Selama manifest tersedia, discovery tidak dijalankan sama sekali. Inilah tujuan cache sekaligus jebakan utamanya saat development.
Konfirmasi. Pada development Panel menulis log:
[panel] The cached panel manifest is out of date: the classes under the discovery paths have
changed since `php artisan panel:cache` last ran. …2
Check membandingkan fingerprint discovery path — jumlah file dan mtime terbaru — hanya berjalan jika manifest tersedia, dan tidak pernah dijalankan di production.
Perbaikan.
php artisan panel:clear # development
php artisan panel:cache # deploy time, after the code is in place2
panel:cache dan panel:clear diregistrasikan sebagai hook optimize, sehingga php artisan optimize dan optimize:clear ikut menjalankannya.
Icon Tidak Tergambar
Gejala. ->icon('shield') menghasilkan ruang kosong tanpa icon.
Penyebab. Icon registry merupakan build-time allowlist. Lucide memiliki ribuan icon, tetapi hanya icon yang benar-benar dideklarasikan Panel yang masuk bundle. Nama yang tidak ada pada resources/js/panel/icons/registry.ts tidak dirender.
Perbaikan.
php artisan panel:icons # rewrite the registry from the icons your panels declare
php artisan panel:icons --check # fail instead of writing, for CI
npm run build2
3
Command memindai app/ dan source framework sendiri untuk seluruh bentuk deklarasi icon. Source framework tidak boleh dilewati karena banyak icon yang muncul berasal dari Action dan component bawaan package. Setiap nama kemudian diverifikasi terhadap icon yang benar-benar dikirim Lucide; icon tidak valid membuat command gagal sambil menyebutkan namanya. Pada development, frontend juga memberi warning sekali per unknown icon.
Component Tidak Ada di Registry
Gejala. Custom Widget menampilkan fallback atau Custom Column cell kosong.
Penyebab. Component name di-resolve melalui import.meta.glob terhadap resources/js/pages/Panels/**, yang berfungsi sebagai build-time allowlist. Ada tiga alasan sebuah nama tidak ditemukan dan dari sisi UI hasilnya terlihat sama: typo pada component name, file berada di luar directory yang di-glob, atau build belum dijalankan ulang.
Perbaikan. Letakkan component di bawah resources/js/pages/Panels/{Panel}/… dengan path yang persis sama dengan nama yang dideklarasikan di sisi PHP, lalu rebuild. Pada development, registry memberi warning sekali per unknown name sekaligus menyebut directory tempat component seharusnya berada.
Publish Tidak Melakukan Apa Pun
Gejala. vendor:publish --tag=panda-panel-assets melaporkan tidak ada file yang dipublish, atau component yang seharusnya berubah setelah composer update tetap menggunakan versi lama.
Penyebab. vendor:publish melewati file yang sudah ada. Satu-satunya mode lain adalah --force, tetapi mode tersebut menimpa semua file, termasuk file yang sengaja Anda edit. vendor:publish tidak dapat membedakan stale copy dari modified copy karena keduanya sama-sama "berbeda dari file package saat ini".
Perbaikan. Gunakan command yang menyimpan third comparison value:
php artisan panel:assets # what is behind, what you changed, what conflicts
php artisan panel:assets --update # writes only files you never had, or never edited
npm run build2
3
Jika panel:assets memperingatkan bahwa .panel-assets.json tidak tersedia, jalankan --update sekali untuk membuat manifest, lalu commit file tersebut.
Asset Conflict
Gejala. panel:assets melaporkan CONFLICT dan tidak menulis file yang conflict.
Penyebab. File berubah pada aplikasi dan upstream package. Tidak ada copy yang aman untuk dibuang. Mencoba menyelesaikan conflict secara otomatis dengan tebakan adalah cara upgrade menghapus pekerjaan developer.
Perbaikan.
diff resources/js/panel/tables/DataTable.vue \
vendor/chocoalano/panel/resources/js/panel/tables/DataTable.vue
# merge by hand, then:
php artisan panel:assets --force2
3
4
5
--force memperluas overwrite ke file yang Anda edit, tetapi tidak menghidupkan kembali file yang sengaja dihapus dan tidak memulihkan file yang tidak lagi dikirim package. Conflict juga bukan process error — panel:assets tetap exit 0, karena menggagalkan deployment hanya karena sebuah file sengaja diedit developer merupakan behavior yang salah.
panel:user Menolak
| Pesan | Penyebab | Perbaikan |
|---|---|---|
No auth guard named [x]. | auth.guards.x.provider bukan string | Periksa config/auth.php atau hapus --guard= |
The [users] user provider names no model this command can create. | Provider tidak memiliki key model, atau class model tidak tersedia | Gunakan --guard= yang ditopang Eloquent provider |
The name field is required. pada script | Non-interactive run tanpa seluruh option wajib | Berikan --name=, --email=, dan --password=; prompt dilewati jika input tidak interactive |
The user could not be created: … | Save melempar exception, paling sering unique constraint pada email | Command hanya create, bukan update |
| Tidak ada access line sama sekali | --panel= menunjuk ID yang tidak ada, atau tidak ada Panel yang diregistrasikan | Periksa ID melalui route:list --name=panel. |
Broadcasting Tanpa Broadcaster
Gejala. Echo has not been configured, dilempar dari onMounted, lalu diikuti banyak warning Slot "default" invoked outside of the render function yang tidak menyebut broadcaster sama sekali.
Penyebab. Secara default Panel mencoba subscribe ke live notification channel miliknya. Pada aplikasi tanpa broadcast connection, client memanggil echo() terhadap channel yang tidak memiliki server/driver yang dapat melayaninya.
Behavior saat ini. Panel hanya mengirim channel ke frontend jika broadcast connection benar-benar usable: broadcasting.default menunjuk connection, connection tersebut memiliki driver, dan driver bukan null atau log. Kedua driver tersebut memang valid pada Laravel tetapi tidak dapat dipakai browser untuk membuat live connection.
Perbaikan, sesuai kebutuhan.
$panel->broadcasting(false); // this panel does not want live notificationsatau konfigurasi real broadcaster:
BROADCAST_CONNECTION=reverbphp artisan reverb:start # development needs the websocket server runningJika websocket server tidak berjalan, browser akan retry di background dan Panel tetap bekerja, hanya tanpa live notification.
Composer Menolak
| Pesan | Penyebab |
|---|---|
requires php ^8.2 | PHP di bawah 8.2. |
requires ext-zip | PHP zip extension belum terpasang. Ini hard requirement karena file XLSX adalah zip archive. |
laravel/framework[v11.x] … found … but it does not match your constraint | Laravel 11 tidak didukung dan memang tidak dapat didukung: seluruh release 11.x terkena unpatched advisory dan Composer tidak dapat menyelesaikan dependency terhadapnya. |
| Tidak dapat me-resolve PHP 8.2 dengan Laravel 13 | Laravel 13 membutuhkan PHP 8.3. Pengguna PHP 8.2 harus menggunakan Laravel 12. |
Lihat Compatibility untuk matrix lengkap.
Dua Boot-Time Exception Lain
Keduanya sengaja dilempar pada saat boot, ketika masalah masih murah dan mudah ditemukan, daripada dibiarkan menjadi Page yang diam-diam merender route/behavior yang salah.
| Pesan Exception Mengandung | Arti |
|---|---|
already registered | Dua Panel menggunakan ID yang sama. ID berasal dari nama provider class kecuali ->id() mengubahnya. |
already used by the panel [first] | Dua Panel menggunakan path yang sama pada domain yang sama. Gunakan path() berbeda atau domain() berbeda. |
| colliding route path | Dua Resource dalam satu Panel mengklaim path shape yang sama — misalnya Page ManageRelatedRecords pada projects/{record}/tasks dan nested Resource pada projects/{parentRecord}/tasks. Bagi router Laravel keduanya adalah pattern yang sama dan salah satunya akan menjadi unreachable jika tidak dihentikan saat boot. |
Lihat Juga
- Running panel:install — check yang menghasilkan diagnosis di dokumen ini
- Frontend requirements — npm package, host module, dan layout rule
- Opening your first panel, Creating the first user
- Troubleshooting: panel routes 404, 403, host modules, Vite, Tailwind, icons, asset conflicts, broadcasting, login redirects, Inertia root view
- Concepts: authorization, caching