instructure/canvas-lms · error · ActiveRecord::Rollback

Failed deleting an event from the series, update not saved

Error message

Failed deleting an event from the series, update not saved

What it means

Guard inside update_from_series' transaction: when persisting an updated recurring calendar event series, updating one of the per-occurrence events failed (event.update or save returned false). The whole transaction is rolled back so the series is left consistent, and this sentinel error reports which event failed.

Solutions

  1. Check the event's errors collection for the actual validation failure (e.g. invalid start_at/duration or context constraints)
  2. Verify the rrule change doesn't leave events outside the RRULE's occurrences
  3. Retry the update with corrected params; ensure the caller passes valid series update attributes
Defensive patterns

Strategy: try-catch

When it happens

Trigger: Thrown at app/controllers/calendar_events_api_controller.rb:1077 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15). Data as JSON: /api/errors/eda542cb0ca8a1dd. Report an issue: GitHub.

Appendix: source

Thrown at app/controllers/calendar_events_api_controller.rb:1077

    events = events.to_a
    update_limit = rrule_changed ? RruleHelper::RECURRING_EVENT_LIMIT : events.length

    events.each do |ev|
      ev.saving_user = @current_user
    end

    error = nil
    CalendarEvent.skip_touch_context do
      CalendarEvent.transaction do
        dtstart_list = rr.present? ? rr.all(limit: update_limit) : []
        if rr.present? && events.length > dtstart_list.length
          # truncate the list of events we're updating to how many
          # we'll end up with given the (possible updated) rrule
          events.drop(dtstart_list.length).each do |event|
            unless event.grants_any_right?(@current_user, session, :delete)
              error = { message: t("Failed deleting an event from the series, update not saved"), status: :unauthorized }
              raise ActiveRecord::Rollback
            end

            unless event.destroy
              error = { message: t("Failed deleting an event from the series, update not saved") }
              raise ActiveRecord::Rollback
            end
          end
          events = events.take(dtstart_list.length)
        end

        if new_series_head
          events[0].series_head = true
        end

        dtstart_list.each_with_index do |dtstart, i|
          params_for_update = set_series_params(params_for_update, dtstart, duration)
          event = events[i]
          event.update_all = true if which != "one" && event&.series_uuid && event.series_head

View on GitHub (pinned to 1c9f0bb801)