Context
Running each project rake task in this repo (bundle exec rake <name>) surfaces a cluster of bugs in the tasks driven by Heroku Scheduler. Three tasks crash on every invocation; two more crash latently when production data shape triggers them.
This issue covers the "broken in production" bugs only. Maintainability cleanup (auto_annotate noise, factory_bot:lint debt, deployment/ pruning, in-task schedule-guard anti-pattern) and moving controller specs to request specs are tracked separately.
Bugs that crash on every run
1. send_case_contact_types_reminder — NoMethodError: undefined method 'every' for main
lib/tasks/send_case_contact_types_reminder.rake:4 and lib/tasks/send_no_contact_made_reminder.rake:4 both wrap their work in:
every 1.weeks do
CaseContactTypesReminder.new.send!
end
every is from the whenever gem (intended for config/schedule.rb), not a Rake primitive. The block raises immediately when the task runs — meaning the case-contact-types SMS reminder has not actually executed since that block was added.
2. send_no_contact_made_reminder — task name doesn't exist
lib/tasks/send_no_contact_made_reminder.rake declares task send_case_contact_types_reminder: :environment do … — the same task name used by the other file. rake -T confirms only one task is registered, with both descriptions concatenated:
rake send_case_contact_types_reminder # Send an SMS … past 60 or more days / Send an SMS … two weeks have passed …
So Heroku Scheduler invocations of send_no_contact_made_reminder fail with "Don't know how to build task", and the no-contact-made SMS reminder has never run. The file also require_relatives the wrong service file and instantiates CaseContactTypesReminder instead of NoContactMadeReminder.
3. recurring:init — NameError: uninitialized constant ExampleRecurringTask
lib/tasks/recurring_jobs.rake:3 calls ExampleRecurringTask.schedule!, but ExampleRecurringTask is defined in lib/tasks/example_recurring_task.rb which Rails does not autoload. The class is also dead example code:
def perform
Bugsnag.notify("This is just ExampleRecurringTask saying hi in #{Rails.env}")
end
— likely safe to delete entirely.
Latent bugs that crash when data triggers them
4. youth_birthday_reminder — NoMethodError: undefined method 'volunteer_id' for nil
lib/tasks/youth_birthday_reminder.rake:6:
.deliver(Volunteer.find_by(id: casa_case.case_assignments.first.volunteer_id))
When a CasaCase.birthday_next_month case has no case_assignments, .first is nil. Confirmed via isolated repro against dev DB:
$ rails runner 'cc = CasaCase.birthday_next_month.first; cc.case_assignments.destroy_all; cc.case_assignments.first.volunteer_id'
RAISED: NoMethodError: undefined method 'volunteer_id' for nil
Seed data happens to have ≥1 assignment per case, so the bug never fires in test/dev — but it will fire in production whenever a case is briefly without an active assignment.
.first also ignores active vs. inactive — should be case_assignments.active.
5. emancipation_checklist_reminder_notifier (in development/notifications.rake) — same bug as #4
lib/tasks/development/notifications.rake:6 has the identical casa_case.case_assignments.first.volunteer_id shape and will crash the same way. The whole development/notifications.rake file is also missing an if Rails.env.development? guard — so the dev tasks followup_notifier (Followup.all.first) and reimbursement_complete_notifier (CaseContact.all.first) could be triggered against prod data.
Proposed PR scope
Single PR titled "Fix broken Heroku Scheduler rake tasks":
How verified
Ran every project-defined rake task against current dev DB (35 cases, 7 volunteers, 2 birthday-next-month cases, 0 followups; today is Saturday May 2 so monday? / day == 1 guards short-circuit the digest tasks):
| Task |
Result |
send_case_contact_types_reminder |
exit 1 — NoMethodError: undefined method 'every' |
recurring:init |
exit 1 — NameError: uninitialized constant ExampleRecurringTask |
youth_birthday_reminder (with case_assignments empty) |
confirmed NoMethodError via isolated repro |
send_no_contact_made_reminder |
task name not registered (collides with send_case_contact_types_reminder) |
clear_passed_dates, court_report_due_reminder, volunteer_birthday_reminder, send_learning_hour_reports, factory_bot:lint, test_checker |
exit 0, no crash |
post_gc_stat_to_discord was skipped during verification because it HTTP-fetches the production URL — that's a separate concern (P3).
Context
Running each project rake task in this repo (
bundle exec rake <name>) surfaces a cluster of bugs in the tasks driven by Heroku Scheduler. Three tasks crash on every invocation; two more crash latently when production data shape triggers them.This issue covers the "broken in production" bugs only. Maintainability cleanup (auto_annotate noise,
factory_bot:lintdebt,deployment/pruning, in-task schedule-guard anti-pattern) and moving controller specs to request specs are tracked separately.Bugs that crash on every run
1.
send_case_contact_types_reminder—NoMethodError: undefined method 'every' for mainlib/tasks/send_case_contact_types_reminder.rake:4andlib/tasks/send_no_contact_made_reminder.rake:4both wrap their work in:everyis from thewhenevergem (intended forconfig/schedule.rb), not a Rake primitive. The block raises immediately when the task runs — meaning the case-contact-types SMS reminder has not actually executed since that block was added.2.
send_no_contact_made_reminder— task name doesn't existlib/tasks/send_no_contact_made_reminder.rakedeclarestask send_case_contact_types_reminder: :environment do …— the same task name used by the other file.rake -Tconfirms only one task is registered, with both descriptions concatenated:So Heroku Scheduler invocations of
send_no_contact_made_reminderfail with "Don't know how to build task", and the no-contact-made SMS reminder has never run. The file alsorequire_relatives the wrong service file and instantiatesCaseContactTypesReminderinstead ofNoContactMadeReminder.3.
recurring:init—NameError: uninitialized constant ExampleRecurringTasklib/tasks/recurring_jobs.rake:3callsExampleRecurringTask.schedule!, butExampleRecurringTaskis defined inlib/tasks/example_recurring_task.rbwhich Rails does not autoload. The class is also dead example code:— likely safe to delete entirely.
Latent bugs that crash when data triggers them
4.
youth_birthday_reminder—NoMethodError: undefined method 'volunteer_id' for nillib/tasks/youth_birthday_reminder.rake:6:When a
CasaCase.birthday_next_monthcase has nocase_assignments,.firstisnil. Confirmed via isolated repro against dev DB:Seed data happens to have ≥1 assignment per case, so the bug never fires in test/dev — but it will fire in production whenever a case is briefly without an active assignment.
.firstalso ignores active vs. inactive — should becase_assignments.active.5.
emancipation_checklist_reminder_notifier(indevelopment/notifications.rake) — same bug as #4lib/tasks/development/notifications.rake:6has the identicalcasa_case.case_assignments.first.volunteer_idshape and will crash the same way. The wholedevelopment/notifications.rakefile is also missing anif Rails.env.development?guard — so the dev tasksfollowup_notifier(Followup.all.first) andreimbursement_complete_notifier(CaseContact.all.first) could be triggered against prod data.Proposed PR scope
Single PR titled "Fix broken Heroku Scheduler rake tasks":
every 1.weeks do … endandevery 1.days do … endblocks in both reminder rake files (test issue #1)send_no_contact_made_reminder.raketosend_no_contact_made_reminderand wire it toNoContactMadeReminder(to do: make the app #2)lib/tasks/case_contact_types_reminder.rb,no_contact_made_reminder.rb,supervisor_weekly_digest.rbtoapp/services/; drop therequire_relativelines from their rake files and specs so Rails autoload picks them up (cleanup tied to test issue #1 / to do: make the app #2)lib/tasks/recurring_jobs.rakeandlib/tasks/example_recurring_task.rb(or move the class toapp/jobs/and gut the Bugsnag noise) (Volunteer #3)case_assignments.active.find_eachinyouth_birthday_reminder.rake(Admin #4)lib/tasks/development/notifications.rakeinif Rails.env.development?and apply the same nil-safety to the emancipation notifier (Admin view/edit individual volunteer #5)How verified
Ran every project-defined rake task against current dev DB (35 cases, 7 volunteers, 2 birthday-next-month cases, 0 followups; today is Saturday May 2 so
monday?/day == 1guards short-circuit the digest tasks):send_case_contact_types_reminderNoMethodError: undefined method 'every'recurring:initNameError: uninitialized constant ExampleRecurringTaskyouth_birthday_reminder(withcase_assignmentsempty)NoMethodErrorvia isolated reprosend_no_contact_made_remindersend_case_contact_types_reminder)clear_passed_dates,court_report_due_reminder,volunteer_birthday_reminder,send_learning_hour_reports,factory_bot:lint,test_checkerpost_gc_stat_to_discordwas skipped during verification because it HTTP-fetches the production URL — that's a separate concern (P3).