Fix retry loop in NameError job recovery initializer

GoodJob's `.discarded` scope is defined as `finished.where.not(error: nil)`,
which matches any finished job with an error — including jobs with
`error_event: :retried` that already have a pending retry scheduled.

On every restart, the initializer was finding these already-retried jobs
and calling `retry_job` again. Thankfully good_job has us covered and
prevent a new retry job from being queued. This is visible with
`ActionForStateMismatchError` or `PG::UniqueViolation` errors on each
boot. Not harmful, but far from ideal.

Symptoms visible in the logs on every restart:

  Failed to enqueue job for retry SomeJob (job id: b03926e2-...):
  PG::UniqueViolation: ERROR: duplicate key value violates unique
  constraint "good_jobs_pkey"
  DETAIL: Key (id)=(a798492e-...) already exists.

Exclude jobs with `error_event: :retried` so only truly stuck jobs
(unhandled, retry_stopped, discarded) are re-queued.
This commit is contained in:
Christophe Bliard
2026-06-10 09:44:49 +02:00
parent dc4cd9a6b4
commit 80c150c2aa
@@ -42,6 +42,7 @@ Rails.application.configure do
GoodJob::Job
.discarded
.where.not(error_event: GoodJob::ErrorEvents::RETRIED) # reject discarded jobs that were already retried
.where("error LIKE ?", "NameError: uninitialized constant %")
.filter do |job|
# Only retry jobs with NameError related to the job class name.