Skip to content

Extension Troubleshooting

Capell Extension Troubleshooting screenshot Capell Extension Troubleshooting screenshot

Use this when a package extension does not appear, does not run, or behaves differently between admin and public requests. Start with the smallest check that proves whether Capell can see the package, then move toward the specific runtime.

For focused debugging paths, use:

ProblemRunbook
Composer, manifest, or provider discoveryDebugging package discovery
Admin pages, fields, actions, widgets, settingsDebugging admin extensions
Public output, cache bypasses, unsafe HTMLDebugging public output
Marketplace connection, verification, heartbeatDebugging Marketplace

Run these before changing code:

Terminal window
composer dump-autoload
php artisan optimize:clear
php artisan list capell
php artisan capell:package-cache:clear

If the package contributes admin configurators or widgets, also run:

Terminal window
php artisan capell:admin-clear-cache
php artisan capell:admin-cache-configurators
php artisan capell:admin-cache-widgets

Confirm the package service provider is loaded through Composer discovery, the host app’s provider list, or the package’s capell.json provider entries. A missing provider is the most common reason every downstream extension point appears broken.

SymptomLikely causeCheckFix
php artisan list capell does not show package commandsComposer autoload or provider discovery is stalecomposer show capell-app/<package> and composer dump-autoload -oReinstall/update the package, fix composer.json autoload, then clear Laravel and Capell package caches.
Package appears in Composer but not in Capell package statecapell.json is missing, invalid, or not loadedInspect capell.json; run package manifest tests when availableFix manifest name, providers, surfaces, and version constraints, then run php artisan capell:package-cache:clear.
Install/setup runs but package data is missingInstall command skipped settings migrations or package setup actionsCheck package install command output and php artisan migrate:statusRegister settings migrations and run setup through Actions rather than writing from providers.

Composer drift means capell_extensions and the current Composer/package registry no longer agree. The Extensions dashboard reports drift as a health alert, but it is read-only: loading /admin/extensions must never run composer require.

Capell classifies drift into four reasons:

ReasonWhat it meansRepair path
Missing registry manifestA capell_extensions row exists, but the current registry has no manifestReview the record manually. The package may have been removed, renamed, or stopped registering metadata.
Composer unavailableThe registry manifest exists, but Composer does not expose the packageRun php artisan capell:extensions:repair-composer-drift vendor/example.
Version mismatchComposer exposes a different version than the Capell extension recordRun the repair command, then verify the extension install/upgrade path if metadata still disagrees.
Disabled or failed in CapellComposer exposes the package, but capell_extensions.status blocks runtime useReview status, runtime gate, and recent install/upgrade failures before re-enabling the extension.

For one package, run:

Terminal window
php artisan capell:extensions:repair-composer-drift vendor/example

For scheduled or operator-approved bulk repair, enable the gate first:

Terminal window
CAPELL_EXTENSIONS_COMPOSER_DRIFT_AUTO_FIX=true
php artisan capell:extensions:repair-composer-drift --all

--all --force bypasses the config gate for a single manual run. Use it only when you have already reviewed the dashboard alerts and know the drift is Composer-actionable.

The latest repair attempt is recorded on capell_extensions.metadata with composer_drift_last_repair_attempted_at, composer_drift_last_repair_status, composer_drift_last_repair_message, and composer_drift_last_detected_reason. The dashboard alert includes the latest repair status/message when present.

SymptomLikely causeCheckFix
Resource/page/widget does not show in navigationContribution was not registered, permission denies access, or navigation is intentionally suppressedCheck the package admin provider, AdminBridge::register(), and the user’s permissionsPrefer AdminBridgeRegistrar::resource(), page(), widget(), or filamentDashboardWidget(). Re-run capell:admin-install when permissions changed.
An Extensions page edit action is missingThe page was registered as a normal page instead of an extension pageSearch for registerExtensionPage(...)Register the package control page with CapellAdmin::registerExtensionPage($packageName, PageClass::class).
Dashboard Filament widget is registered but disabledWidgets are available but admin settings hide themCheck Admin settings and widget defaultsUse registerOverviewStat() for small metrics or enable the widget through Admin settings or setEnabledWidgets().
Form fields are missingWrong extender tag, wrong hook enum, or configurator cache is staleCheck tags such as PageSchemaExtender::TAG and SiteSchemaExtender::TAGTag the extender in the provider or AdminBridgeRegistrar::schemaExtender(), then clear/cache admin configurators.
Header/table actions are missingExtender targets the wrong surfaceCheck whether the target is page, site, resource, or Extensions pageUse the matching extender tag: PageHeaderActionExtender, SiteHeaderActionExtender, ResourceHeaderActionExtender, PageTableExtender, or ExtensionsPageActionRegistry.
User fields or relation managers are missingUser schema bridge/extender does not support the current contextCheck UserSchemaExtender::supports() or the package UserResourceBridge::isEnabled() logicUse AbstractUserSchemaExtender for no-op defaults, and test the resolver with the same user model/context used by the resource.
Publish panel content is missingThe package used a page schema extender instead of PublishPanelExtenderSearch for PublishPanelExtender::TAGTag a PublishPanelExtender and return a View, HTML string, or null from extendPanel().
Admin route works on one host but not anotherCAPELL_ADMIN_PATH or CAPELL_ADMIN_DOMAIN is cachedphp artisan config:show capell-admin.path and php artisan config:show capell-admin.domainUpdate env/config and run php artisan optimize:clear. Signed preview URLs must be regenerated after host/path changes.
SymptomLikely causeCheckFix
Settings group is absentSettings class or schema was not registeredSearch for SettingsSchemaRegistry::registerSettingsClass() and register()Register both the settings class and schema, or use AdminBridgeRegistrar::settingsClass() and settingsSchema().
Settings page label/icon is genericMetadata is missingSearch for registerMetadata(new SettingsGroupMetadata(...))Register metadata with translated labels and the correct group key.
Settings save fails on fresh installsSettings migration did not run or is not idempotentCheck database/settings/ and install/setup command registrationAdd guarded settings migrations and cover fresh install plus upgrade paths.
Settings appear in tests but not browserConfig/package cache is stale or provider boot order differsClear caches and inspect provider registration timingRegister settings in boot() or after resolving SettingsSchemaRegistry when package load order matters.
SymptomLikely causeCheckFix
Render hook output is absentWrong location, scenario, target, or provider timingSearch for RenderHookRegistry::register(...); compare location/scenario/target with the Blade callRegister in boot() and match the exact RenderHookLocation, scenario, and target used by the component.
Public page route catches package/admin URLsPath was not reserved before the frontend fallback routeInspect ReservedFrontendPathRegistry registrations and route orderReserve exact paths or prefixes from the package provider, then clear route/config cache.
Public package route returns 404Route file/provider was not loaded or frontend fallback owns the path firstphp artisan route:list | grep <path>Load the package route provider and reserve the path if it should not fall through to page rendering.
Public page middleware runs in the wrong orderPackage middleware was appended/prepended without considering frontend resolutionInspect FrontendRouteMiddlewareRegistry::all() in a focused testUse insertAfter() or insertBefore() around a known middleware instead of broad prepend/append.
Component alias resolves to a raw Blade nameComponent was registered with Blade/Livewire but not FrontendComponentRegistryCheck FrontendComponentRegistryInterface::has() and hasReference()Register a stable key and aliases through FrontendComponentRegistryInterface.
Frontend rule condition never matchesCondition key differs from the stored settings/runtime ruleSearch for FrontendRuleCondition::key() and the stored rule keyRegister the condition class and keep the key stable; cover it with a direct condition test.
HTML cache bypasses a pagePublic output contains authoring markers, field paths, model IDs, package internals, or signed admin URLsCheck response headers for X-Frontend-Cache: BYPASS; inspect rendered HTML as anonymous userRemove authoring state from public Blade. Frontend authoring must load after page load from an authenticated admin beacon.
Tailwind classes are missingPackage sources/imports were not registered or Vite cannot resolve a symlinked dependencyRun the frontend asset report command when installed; inspect TailwindAssetsRegistry::toReport() in testsRegister sources/imports through TailwindAssetsRegistry, install missing npm packages, or add a narrow Vite alias.
Page shows old contentStatic HTML or fragment cache is staleCheck queue workers, the installed cache package’s output path, and cache invalidation registrationsRun php artisan capell:html-cache:clear when available; if using the HTML cache package, run php artisan capell:static-site; keep queue workers running.
SymptomLikely causeCheckFix
Model changes do not clear package outputThe model was not registered with CacheInvalidationRegistrySearch for registerDependency(Model::class, ...)Register exact cache keys where possible. Wildcard patterns intentionally flush the whole capell-frontend tag.
Invalidation works locally but not productionQueue worker, cache driver, or tag support differsCheck QUEUE_CONNECTION, cache driver, and worker logsUse a supported cache driver for tagged cache behavior and run workers for async invalidation.
Fragment output remains staleFragment uses a different key/surrogate key than invalidation codeCompare @cache(...) keys with invalidation callsAlign surrogate keys and avoid ad hoc cache key construction in Blade.
SymptomLikely causeCheckFix
Package does not appear in browser installerComposer cannot resolve it or manifest metadata is incompletecomposer show capell-app/<package> --available; inspect capell.json provider/scopes/kindFix Composer auth/repositories and manifest metadata, then clear package/config cache.
Package appears but cannot be selected with a themeTheme key/package metadata is missing or requirements are unmetCheck kind, themeKey, extends, and requirements in capell.jsonKeep theme metadata in the manifest and make the package installable before opening /install.
Install guide patch is missingPatch was not registered in PatchRegistry or probe() says it is not applicableSearch registerPatches() and inspect the patch reason()Register the patch, keep probe() idempotent, and cover the host-file state with a patch test.
Catalogue loads but install is blockedSite is not connected or install authorization is denied by Capell AppOpen Marketplace diagnostics and heartbeat stateConnect a Capell account, resolve diagnostics, then request authorization again.
api/registration-sessions route is missingMarketplace API URL uses the old unversioned pathphp artisan config:show capell-marketplace.marketplace.base_urlUse https://capell.app/api/v1, then run php artisan config:clear.
Domain verification failsExact host mismatch, expired challenge, or public .well-known path blockedFetch the challenge URL from outside the serverVerify the exact production host, remove auth/CDN blocks, and restart verification.
Account linking callback failsStale approval URL, expired session, invalid state, or missing APP_URL hostLatest marketplace_account_connection_sessions.last_errorSet APP_URL, clear config, and start a fresh account connection from the same browser session.
Heartbeat fails after account linkingNo public webhook URL, no instance, or Marketplace API unreachablePhoneHomeAction::lastFailureMessage() and latest marketplace_instances rowSet CAPELL_MARKETPLACE_WEBHOOK_URL when needed, confirm network access, and run heartbeat again.

Add or update a focused test when the issue crossed one of these boundaries:

  • package discovery, manifest validation, or install/setup behavior;
  • admin resources, settings, widgets, extenders, permissions, or navigation;
  • public rendering, route fallback, render hooks, cache output, or Tailwind assets;
  • marketplace authorization, account linking, diagnostics, or domain verification.

For public output, test anonymous and non-admin responses directly. Cached/static HTML must match the same safe output and must not contain authoring markers, model IDs, field paths, selectors, signed admin URLs, or package internals.