Find the symptom, apply the fix. When nothing here matches, run php artisan optimize:clear, reproduce the problem with APP_DEBUG=true on a development copy, and read storage/logs.
| Symptom | Cause and fix |
|---|---|
Class "Modules\Name\..." not found right after adding a module | Composer has not merged the module's autoload map. Run composer dump-autoload |
| Plugin is installed but nothing appears | It is inactive. Activate it in Appearance → Plugins (or php artisan module:enable Name), then php artisan optimize:clear |
| "Required plugin is not active" on activation | A module in requires is missing, inactive or outside the version range. Activate it first, or fix the constraint |
| Upload rejected with a manifest error | See Common manifest errors. Most often: name does not match the folder, a provider file is missing, or the ZIP contains more than one top folder |
| Upload says the plugin is already installed | The upload flow does not update plugins. Replace the files instead (Updating a plugin) |
| Table not found | The Plugin Manager does not migrate. Run php artisan migrate |
| Symptom | Cause and fix |
|---|---|
New route returns 404, or Route [x] not defined | Routes are cached (often after saving an .env-backed setting). php artisan optimize:clear |
| Your page renders without the admin sidebar or with the wrong theme | The route group is missing AdminTheme (admin) or FrontTheme (public) |
| Breadcrumb exception on an admin page | Every named page route needs a Breadcrumbs::for() definition, and your provider must require the breadcrumbs file |
| 403 for a user who should have access | Check the exact permission string on the route (php artisan route:list --name=... shows the middleware), that the permission exists, and that the role has it. Spatie caches permissions: php artisan permission:cache-reset |
| 403 on the widgets screen for non-super-admins | Known gap: the screen checks permissions that are not seeded. See Known quirks |
| Sidebar item missing | Registered in boot() instead of an AdminBooting listener, or the user lacks the permission your menu helper checks |
Settings screen crashes with a TypeError about an array | A label equals a language file name ('Pages', 'Settings'). Use a namespaced key |
| A switch can never be turned off | Unchecked boxes are absent from the request; give the field 'default' => 0 (or 'no') |
| Admin request is slow | Settings pages built eagerly, or queries in boot(). Pass a closure and defer queries to render time |
| Symptom | Cause and fix |
|---|---|
__('alias::file.key') prints the key | Your provider does not override registerTranslations() to register the namespace (see how) |
| Translated attribute read fails with a class-not-found error | The model lacks public string $translationModel = ...::class; |
| Arabic page shows English content | No translation row for that locale and the fallback is used. Check the {model}_translations table |
| Symptom | Cause and fix |
|---|---|
| Unable to locate file in Vite manifest | The entry is not built. Add it to input in vite.config.js and npm run build, or stop a stale npm run dev (delete public/hot) |
| Sass change does not show on the site | The site serves the compiled theme CSS. Rebuild, then Regenerate Theme CSS, then hard-refresh |
| Saved colours do not show | Regenerate the theme CSS, clear the response cache, hard-refresh. With a custom theme, check it has its own assets/sass/app.scss entry |
| Menu change has no effect on one page | The page pins a menu in its settings |
New theme.json or option not picked up | php artisan theme:refresh-cache |
| Theme option exists but nothing changes visually | Only a fixed set of options reaches the compiled CSS. Use your option in markup (example) |
| Symptom | Cause and fix |
|---|---|
| Your block is not in the editor | The shortcode is not registered in boot(), its definition is disabled, or the id clashes with another one (register() throws; registerIfMissing() silently keeps the first) |
| Block preview is empty or errors | The preview only passes attributes declared in your defaults or traits. Open the browser network tab and read the preview response |
A whole page shows raw <x-shortcode-...> markup | One shortcode on the page cannot compile, usually because its plugin is disabled. Re-enable it or remove the block |
| Block assets do not load | Declare them on the shortcode definition; check the files exist (built or published) |
| Data-bound section shows old data | The record changed outside Eloquent, or through a model not watched by the binding source. Run php artisan pages:refresh-bound and check the source's watched models |
| Symptom | Cause and fix |
|---|---|
| Visitors see stale content after an edit | The model that changed does not flush the response cache. Extend BaseModel or register it with ResponseCacheInvalidator::flushWhenChanged(); remember translation and media models |
| One visitor sees another's data | A personal page is cached. Remove doCache from the route or call CacheProfile::keepOutOfCache() where the personal data is added |
| Validation errors disappear after redirect | Not caused by the cache: pages with flash data are never cached or served from cache. Check the form's redirect and error bag |
| Symptom | Cause and fix |
|---|---|
| Scheduled task never runs | The server cron does not call schedule:run, or the plugin is inactive. Check php artisan schedule:list |
| Queued jobs never run | The site uses a real queue but no worker runs. Start one, or switch back to sync |
| No e-mails arrive | The mailer is still log (mail is written to the log). Configure Settings → Mail |
| Symptom | Cause and fix |
|---|---|
| Plugin tests fail with "no such table" or behave without a database | The test file lacks uses(TestCase::class, RefreshDatabase::class);, or the plugin is not enabled |
| Route-related tests fail only on your machine | Routes or config are cached. php artisan optimize:clear |
Attempted request to [...] without a matching fake | Tests block real HTTP. Add Http::fake() for that service |
| Database file not found | Create the empty database/testing.sqlite |