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

Nova Failed Jobs Tool Laravel Package

kregel/nova-failed-jobs-tool

A Laravel Nova tool for viewing and managing failed queue jobs directly from your admin panel, with retry and delete actions so you can resolve failures without leaving Nova.

View on GitHub
Deep Wiki
Context7

Getting Started

  1. Install via Composer in your Laravel app that already runs Nova:

    composer require kregel/nova-failed-jobs-tool
    

    Pin the version explicitly (kregel/nova-failed-jobs-tool:^1.0) so a future dependency-only bump can't shift what you tested against.

  2. Register the tool in app/Providers/NovaServiceProvider.php:

    public function tools()
    {
        return [
            new \Kregel\NovaFailedJobsTool\NovaFailedJobsTool(),
        ];
    }
    

    If the package doesn't auto-discover its service provider, add Kregel\NovaFailedJobsTool\NovaFailedJobsToolServiceProvider to config/app.php. Check the repo README first — for a low-star, 2021-era tool the README is the single best source of truth on the exact namespace and registration class name.

  3. Ensure the failed_jobs table exists. If you don't already have it:

    php artisan queue:failed-table
    php artisan migrate
    

    (Laravel 8+ ships this migration by default.)

  4. Look here first: open your Nova sidebar, click the "Failed Jobs" tool, and confirm it lists rows from failed_jobs. Compare against the CLI baseline:

    php artisan queue:failed
    

    If the Nova list matches queue:failed, the tool is wired up correctly. If it's empty in Nova but non-empty in CLI, you have a connection/table/guard mismatch — check config/queue.php and the failed_jobs table name.

  5. First real use case: force a failure to test the workflow. Push a job that throws (e.g. a job whose handle() calls throw new \Exception('test')), run php artisan queue:work --once, then open the tool and inspect the decoded payload and exception. That teaches you what the tool actually renders before you rely on it in an incident.

Implementation Patterns

Daily triage loop. Treat the Nova tool as the read/decide surface and the CLI as the bulk-action surface. A repeatable workflow:

  • Morning: open the tool, sort/filter by failed_at descending.
  • Inspect the exception to classify: transient (timeout, deadlock, upstream 5xx), code bug (TypeError, missing class), or data bug (bad payload).
  • Retry transient failures individually from the tool; fix deploys for code bugs first, then retry in bulk.
  • Bulk-retry the rest with php artisan queue:retry all (or a filtered set of IDs), since the tool is per-job oriented.

Integrate with your logging stack. The exception column is often truncated in the UI. Copy the job uuid and grep your structured logs (storage/logs/laravel.log or your log aggregator) for that UUID — many teams add the job UUID to log context in a JobProcessing/JobFailed event listener, which makes the Nova row a jumping-off point rather than the sole source of truth.

Deploy-safe retry pattern. Failed jobs are serialized snapshots of old code. After a deploy that changes a job's constructor or dependencies, retrying an old failed job can fail again with a ModelNotFoundException or unserialize error. The practical rule: only retry jobs whose failure predates the deploy if you know the payload shape didn't change. Otherwise, delete and let the originating process re-enqueue.

Surface failed jobs on a dashboard. The tool is a detail view; for at-a-glance awareness add a Nova metric that counts failed_jobs rows since midnight and a scheduled command (Schedule::command('queue:prune-failed --hours=168') plus an alert when count > 0). Use the tool to drill into the specific rows the metric flagged.

Multi-queue environments. If you run separate queues (e.g. default, emails, webhooks), the tool lists them together unless it offers a filter. Establish a convention — either filter by the queue column in the UI or query failed_jobs directly when you need queue-scoped bulk retries (queue:retry --queue=emails).

Pair with queue:monitor. Laravel's queue:monitor command alerts on queue size, not failures. Combine it with a failed_jobs count check so you're alerted on both backlogs and failures, and use the Nova tool for the human investigation step.

Gotchas and Tips

  • Nova is a hard dependency. This package is useless without a licensed Laravel Nova install. It also needs Nova's asset build pipeline — run php artisan nova:publish and rebuild (npm run dev/prod) if the tool's compiled JS doesn't appear.

  • v1.0.0 is a dependency bump, not a feature release. The only change is "truly support >= php 7.1" — i.e. a widened/normalized php constraint in composer.json. Nothing else moved: no Nova 4/5 support, no Laravel 9/10/11 declaration, no new filters or actions. Do not read the 1.0.0 semver bump as a stability signal or as evidence the package was ported forward; it was previously shipping a version string below 1.0 while the code was unchanged.

  • The widened PHP floor is mostly cosmetic for a modern app. php >=7.1 is a lower bound — it helps legacy installs, but it says nothing about upper bounds or about laravel/nova / illuminate/* constraints. On a PHP 8.2 + Laravel 11 + Nova 5 app you'll still hit the Nova/Illuminate constraint wall before the PHP one. Inspect the repo's composer.json for laravel/nova and illuminate/* before composer require; if they pin ^3.0 or ^8.0, avoid --ignore-platform-reqs in production — that's a red flag, not a workaround. Treat it as a fork candidate or a small in-house Nova tool.

  • Low stars / zero dependents is a signal, not a dealbreaker. Very little community validation. Budget time to read the source (it's small) before trusting its retry/delete behavior, and pin it explicitly in composer.json. A dependency-only 1.0.0 release does not change this calculation.

  • The payload column is not human-readable in the DB. It's a base64-encoded serialized job object. If the tool renders it raw or truncated, use php artisan queue:failed for the decoded view, or decode it yourself:

    $job = json_decode(DB::table('failed_jobs')->find($id)->payload, true);
    $command = unserialize(base64_decode($job['data']['command']));
    

    Never unserialize untrusted payloads blindly.

  • Retrying requires the job class to still be resolvable. If the class was renamed, deleted, or its constructor signature changed since the failure, retry will fail again immediately (often with a new, more confusing exception). Verify the class exists and the payload deserializes before retrying en masse.

  • Retries go back to the original connection/queue stored in the payload, not your current defaults. If a queue name was decommissioned, retried jobs can silently sit in a queue with no workers. Confirm queue:work --queue=... is running on the right names.

  • exception is a longtext and stack traces get enormous. Rendering a 200KB stack trace in a Nova detail view can freeze the browser tab. If you hit this, check the package's truncation behavior; otherwise open the record in the DB directly.

  • Deleting is permanent. The tool's delete/forget action removes the row — there's no soft delete. Take a mysqldump/pg_dump of failed_jobs (or SELECT * INTO OUTFILE) before clearing a large batch if you might need the payloads for a post-mortem.

  • failed_at is stored in UTC. Nova may render it in the app's display timezone depending on its config. Don't assume the timestamp matches your local clock when correlating with logs.

  • Authorization is whatever Nova enforces. The tool inherits Nova's gate (Nova::auth), but if you use per-tenant scoping or custom policies, confirm the tool doesn't bypass them — failed jobs contain serialized models and potentially sensitive payloads, so an over-broad viewNova gate is a data-leak risk. Restrict via Nova::auth() middleware or a policy before enabling in multi-tenant installs.

  • Prune proactively. Add queue:prune-failed (or queue:prune-failed --hours=168) to your scheduler. The tool will happily render 500k rows and make the whole Nova app feel slow; the failed_jobs table is one of the fastest-growing tables in a busy app.

  • Extension points are limited. Expect the tool to be a thin UI over the failed_jobs table with list/detail/retry/delete. If you need custom columns or filters, the realistic options are (a) fork the repo and add a Nova Resource, or (b) skip the tool and write a 60-line Nova Resource for a FailedJob model — that's often less work than patching a stale package, and you get Nova 5 compatibility and full-text search for free. v1.0.0 gives you no new hooks, so this trade-off is unchanged.

  • Debugging checklist when the tool misbehaves: verify failed_jobs table name matches config, verify the DB connection the tool uses matches config/queue.php's failed driver, check storage/logs/laravel.log for asset/route registration errors after composer require, and run php artisan nova:asset / php artisan route:list | grep failed to confirm routes registered. After upgrading to 1.0.0, diff composer.lock — the resolved laravel/nova and illuminate/* versions may have moved as a side effect of the constraint change, which is the most likely source of any post-upgrade breakage.

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.
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin