Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Filament Failed Jobs Laravel Package

amvisor/filament-failed-jobs

Filament plugin for inspecting and managing failed queue jobs. Browse failed jobs in a searchable table, review exception details and payloads, then retry or delete entries without leaving your admin panel. Requires a Laravel app using queues and Filament.

View on GitHub
Deep Wiki
Context7

Getting Started

Install and register

composer require amvisor/filament-failed-jobs

Register the plugin in the panel provider where you want the viewer to appear (typically app/Providers/Filament/AdminPanelProvider.php):

use Amvisor\FilamentFailedJobs\FilamentFailedJobsPlugin;

public function panel(Panel $panel): Panel
{
    return $panel
        ->plugin(FilamentFailedJobsPlugin::make());
}

Prerequisite check before anything else

The package reads the standard failed_jobs table. Confirm it exists and that your queues actually record failures:

php artisan queue:failed-table   # only if you don't have the migration
php artisan migrate

If QUEUE_CONNECTION=sync in local dev, nothing will ever land in failed_jobs. Use database or redis with a real worker when testing the viewer.

Where to look first

  1. The README for the exact plugin class name and any config keys (namespaces on small packages drift between Filament versions).
  2. vendor/amvisor/filament-failed-jobs/src/ — usually a *Plugin.php, a Page/Resource class, and possibly a config/ file.
  3. vendor/amvisor/filament-failed-jobs/routes/ or the page's getRouteName() to see the URL slug.
  4. The provider's boot() / register() to spot publishable views, migrations, or config tags.

First use case

Log in to the panel, open the failed-jobs page from the sidebar, and triage a single failing job end to end: inspect the exception, hit Retry, confirm it disappears from the list and appears in your worker logs. That one loop validates installation, permissions, queue config, and payload rendering simultaneously.

Implementation Patterns

Gate it before you ship it

Most of these plugins ship with no authorization beyond panel access. Add a gate or policy check so only trusted roles see raw exception payloads and stack traces (they often contain DSNs, tokens, and user data):

// AuthServiceProvider
Gate::define('viewFailedJobs', fn (User $user) => $user->hasRole('ops'));

// Panel provider, if the plugin exposes a visibility hook
->plugin(
    FilamentFailedJobsPlugin::make()
        ->visible(fn () => auth()->user()?->can('viewFailedJobs'))
)

If no hook exists, fall back to Filament::registerNavigationItems() filtering or override the page's canView()/shouldRegisterNavigation() in a subclass.

Per-panel placement

Register the plugin only on the ops/admin panel. Avoid registering it on customer-facing or multi-tenant panels where failed_jobs is global and would leak across tenants.

Triage workflow that scales

  • Retry for transient failures (timeouts, rate limits, downstream 5xx).
  • Delete for poison jobs after you've captured the payload.
  • Flush only as a last resort; prefer bulk-selecting the specific failures.
  • Copy the exception + payload into your ticket, then delete — keeps the table small and the viewer fast.

Pair with real observability

This viewer is a manual triage UI, not monitoring. Use it alongside Horizon (Redis) or a queue:monitor scheduled command plus alerting. The Filament page is where you act; alerts are how you notice.

Customization

Small packages typically expose limited extension points. Realistic options, in order of preference:

  1. Publishable config/views if the package provides vendor:publish tags — change columns, row limits, slug.
  2. Subclass the Page and re-register it, overriding table() to add columns (e.g. queue, attempts, failed_at) or custom actions.
  3. Custom table action that dispatches a job to re-queue with modified payload, if retry-as-is keeps failing.

Dispatching test failures on demand

Keep a throwaway command handy so you can verify the viewer after upgrades:

// php artisan tinker
dispatch(function () { throw new RuntimeException('viewer smoke test'); });
// then run a worker once, or use ->onConnection('database') and process it

Gotchas and Tips

Version compatibility is the big one. Filament v3 → v4 changed plugin registration, page APIs, and table action signatures. A package with no stars and no recent commits is likely pinned to one major. Check composer.json require constraints and the last commit date before adopting; if it's stale, budget time to fork.

failed_jobs grows unbounded. The viewer paginates, but queries against a multi-hundred-thousand-row table with a LONGTEXT payload are slow. Prune on a schedule (queue:prune-failed --hours=168) and ensure failed_at is indexed (it is by default in the Laravel migration).

Retry is not magic. queue:retry re-pushes the serialized payload. If the job class was renamed, deleted, or its constructor signature changed, retry fails immediately with "class not found" or an unserialize error. Old failures are often unretryable — delete them.

Payloads are truncated or escaped in the UI. Long exception messages and serialized objects get clipped. Don't debug from the table cell; grab the full row:

php artisan tinker
DB::table('failed_jobs')->where('uuid', '...')->first();
# or
php artisan queue:failed

Multi-queue blind spot. The table doesn't group by connection/queue out of the box in most of these viewers. If you run several queues, add a column or filter — otherwise "retry all" can re-trigger jobs onto the wrong queue.

Config caching bites. After changing the plugin registration or its config, run php artisan filament:optimize-clear / php artisan optimize:clear. A cached panel config will hide the page or serve stale settings.

Don't retry in bulk during an outage. If your downstream dependency is still down, a "retry all" turns one incident into a thundering herd. Retry a single job, confirm, then proceed.

Extension ceiling. Expect the package to be a thin wrapper over the failed_jobs table with retry/delete/flush actions. If you need payload diffing, job-class grouping, failure-rate charts, or Slack notifications, plan to build that as a separate Filament widget rather than fighting the package's internals.

Security defaults. Assume no redaction. Exception traces frequently include connection strings and request bodies. Restrict the page, and consider a custom column formatter that masks known-sensitive keys before the payload hits the browser.

Fork-friendly size. The upside of a zero-star package is that it's tiny. If it breaks on a Filament upgrade, the fix is usually a handful of method signatures in one or two files — a 30-minute fork beats waiting for a maintainer.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
mydnic/volet-feature-board-filament-plugin
wmde/email-address
refinery29/test-util
dees040/laravel-api-responses
teamzac/geocoder
ideatica/config-writer
keaton-php/pipe-dream
jacksonwebservices/laravel-user-suite
maksimru/conditional-laravel-debugbar
gismatul/nova-support-chat
gismatul/laravel-support-chat
networkrailbusinesssystems/oracle-api
alphabalex/messaging-made-easy
rawphp/warp
shootkiran/merobug
narakode/fineauth
numencode/wn-syncops-plugin
ibnnajjaar/mib-global-pay
refinery29/php-cs-fixer-config
parsnick/steak