Onboarding reminder step fails with 422, blocking account setup (PUT /api/profiles/:id)
Summary
Completing the check-in reminder step of onboarding fails for every user. PUT /api/profiles/:id
returns 422 Unprocessable Entity and Ember throws The adapter rejected the commit because it was invalid, so onboarding can't be completed.
Both choices on that step fail — picking a reminder time, and choosing "do not remind me" — for two
independent reasons.
Steps to reproduce
- Sign in as a user who hasn't completed onboarding
- Advance to the reminder step
- Either pick a time or select "do not remind me", then continue
PUT /api/profiles/:id → 422
Root cause
frontend/app/components/onboarding/reminder-step.js:22 always sets onboardingReminder = true
before saving, so the scheduling branch in ProfilesController#update runs on every completion of
the step, regardless of what the user chose:
if time_changed || initial_onboarding_reminder
delete_old_job(@profile.reminder_job_id)
job_id = CheckinReminderJob.perform_in(get_reminder_time.minutes, @profile.id, @profile.checkin_reminder_at)
@profile.update_column(:reminder_job_id, job_id)
end
1. "Do not remind me" → NoMethodError
transform_hash_time sets checkin_reminder_at to nil whenever the param is absent, and
get_reminder_time then calls .strftime on it:
NoMethodError: undefined method `strftime' for nil:NilClass
app/controllers/api/v1/profiles_controller.rb:64
2. Picking a time → ArgumentError
@profile.checkin_reminder_at is an ActiveSupport::TimeWithZone, which Sidekiq 7's strict
argument checking rejects:
ArgumentError: Job arguments to CheckinReminderJob must be native JSON types,
but Fri, 21 Aug 2026 20:30:00.000000000 UTC +00:00 is a ActiveSupport::TimeWithZone.
Onboarding reminder step fails with 422, blocking account setup (PUT /api/profiles/:id)
Summary
Completing the check-in reminder step of onboarding fails for every user.
PUT /api/profiles/:idreturns
422 Unprocessable Entityand Ember throwsThe adapter rejected the commit because it was invalid, so onboarding can't be completed.Both choices on that step fail — picking a reminder time, and choosing "do not remind me" — for two
independent reasons.
Steps to reproduce
PUT /api/profiles/:id→ 422Root cause
frontend/app/components/onboarding/reminder-step.js:22always setsonboardingReminder = truebefore saving, so the scheduling branch in
ProfilesController#updateruns on every completion ofthe step, regardless of what the user chose:
1. "Do not remind me" →
NoMethodErrortransform_hash_timesetscheckin_reminder_attonilwhenever the param is absent, andget_reminder_timethen calls.strftimeon it:2. Picking a time →
ArgumentError@profile.checkin_reminder_atis anActiveSupport::TimeWithZone, which Sidekiq 7's strictargument checking rejects: