instructure/canvas-lms · error · Checkpoints::SetIdRequiredError

set_id is required, but was not provided

Error message

set_id is required, but was not provided

What it means

Checkpoints::SectionOverrideUpdaterService#call updates a checkpoint assignment override from a course-section set. It resolves the target section_id from the @override hash's :set_id, falling back to the existing override's set_id. If both are blank it raises SetIdRequiredError because a section override cannot be repointed without knowing which section it applies to.

Solutions

  1. Pass set_id in the override hash passed to the service (the target course section id).
  2. Verify the :id in the payload resolves to an AssignmentOverride with set_type 'CourseSection' and a non-blank set_id; pick the correct override id otherwise.
  3. Add a caller-side presence check on override[:set_id] before invoking the service and surface a clearer API error.
  4. Backfill/correct AssignmentOverride records with blank set_id via a data fix if this comes from bad data.

Example fix

// before
service.call(checkpoint:, override: { id: 42 })
// after
service.call(checkpoint:, override: { id: 42, set_id: course_section.id })
Defensive patterns

Strategy: validation

Validate before calling

raise ArgumentError, 'set_id required' if override[:set_id].blank? && AssignmentOverride.find_by(id: override[:id])&.set_id.blank?

Try / catch

begin
  Checkpoints::SectionOverrideUpdaterService.call(...)
rescue Checkpoints::SetIdRequiredError => e
  render json: { error: 'set_id is required for section overrides' }, status: :bad_request
end

Prevention

When it happens

Trigger: Calling Checkpoints::SectionOverrideUpdaterService.call (or .new(...).call) where @override[:set_id] is absent/nil AND the existing AssignmentOverride record found by @override[:id] has a blank set_id (e.g. a 'Everyone' / no-section override was passed instead of a section-scoped one).

Common situations: Frontend sends an override payload without set_id; the override id points at a group or default 'everyone' override rather than a course-section override; data migration or import created section-type overrides with null set_id.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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

Appendix: source

Thrown at app/services/checkpoints/section_override_updater_service.rb:35

# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.

class Checkpoints::SectionOverrideUpdaterService < ApplicationService
  include Checkpoints::DateOverrider

  def initialize(checkpoint:, override:)
    super()
    @checkpoint = checkpoint
    @override = override
  end

  def call
    override = @checkpoint.assignment_overrides.find_by(id: @override[:id], set_type: AssignmentOverride::SET_TYPE_COURSE_SECTION)
    raise Checkpoints::OverrideNotFoundError unless override

    section_id = @override.fetch(:set_id, nil) || override.set_id

    raise Checkpoints::SetIdRequiredError, "set_id is required, but was not provided" if section_id.blank?

    section = @checkpoint.course.active_course_sections.find(section_id)

    current_section = override.set

    update_override(override:, section:)

    parent_override = @checkpoint.parent_assignment.active_assignment_overrides.find_by(set: current_section)
    raise Checkpoints::OverrideNotFoundError unless parent_override

    update_override(override: parent_override, section:, shell_override: true)

    override
  end

  def update_override(override:, section:, shell_override: false)
    override.set = section if section.id != override.set_id
    apply_overridden_dates(override, @override, shell_override:)

View on GitHub (pinned to 1c9f0bb801)