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::SetIdRequiredError raised by Checkpoints::GroupOverrideCommon#get_group_from_override when the override hash passed in has no :set_id key. The method uses Hash#fetch with a raise-on-missing block, so any group override payload lacking set_id aborts before the group is looked up. It exists to fail fast with a clear message instead of a confusing nil find.
Solutions
- Add set_id (the group id) to the override hash before calling the service
- Ensure the client always submits set_id for group overrides, not only on change
- If the override already exists, read set_id from the persisted AssignmentOverride (override.set_id) as the updater service does
- Rescue Checkpoints::SetIdRequiredError at the controller boundary and return 400 with the message
Example fix
// before
service = Checkpoints::GroupOverrideCreatorService.new(checkpoint, { due_at: t })
// after
service = Checkpoints::GroupOverrideCreatorService.new(checkpoint, { set_id: group.id, due_at: t }) Defensive patterns
Strategy: validation
Validate before calling
raise ArgumentError, 'set_id is required' unless override.is_a?(Hash) && override[:set_id].present? # then call the service Checkpoints::GroupOverrideCreatorService.new(checkpoint, override).call
Type guard
def valid_group_override?(override) override.is_a?(Hash) && override[:set_id].present? end
Try / catch
begin
Checkpoints::GroupOverrideCreatorService.new(checkpoint, override).call
rescue Checkpoints::SetIdRequiredError => e
render json: { errors: ['set_id is required for group overrides'] }, status: :bad_request
end Prevention
- Always send set_id with every override payload, even for partial updates
- Validate override hashes with a schema (presence of set_id) before service calls
- Merge persisted override.set_id into update payloads server-side
When it happens
Trigger: Calling get_group_from_override with an override hash that omits the :set_id key, e.g. creating/updating a group-set checkpoint override from a form that did not submit set_id or called the service with {assignment_override: {...}} minus set_id.
Common situations: API clients posting checkpoint overrides without set_id; frontend diffing code that only sends changed attributes so set_id is dropped on unchanged overrides; refactors that renamed group_id to set_id but callers still send the old key.
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
- set_id is required, but was not provided
- set_id is required, but was not provided
- must be a group assignment in order to create group…
- must be a group assignment in order to create group…
- assessor and assessee required
AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15).
Data as JSON: /api/errors/758d758ddeb2cdab.
Report an issue: GitHub.
Appendix: source
Thrown at app/services/checkpoints/group_override_common.rb:37
module Checkpoints::GroupOverrideCommon
# Differentiaiton tags are allowed to be used as group overrides
# This method determines if the override is associated with a
# differentiation tag in the checkpoint's course
def differentiation_tag_override?(override, checkpoint)
return false unless differentiation_tags_enabled_for_context?(checkpoint)
group = get_differentiation_tag_from_override(override, checkpoint)
if group.nil?
return false
end
group.non_collaborative
end
def get_group_from_override(override, checkpoint)
group_id = override.fetch(:set_id) { raise Checkpoints::SetIdRequiredError, "set_id is required, but was not provided" }
checkpoint.course.active_groups.where(group_category_id: checkpoint.effective_group_category_id).find(group_id)
end
def get_differentiation_tag_from_override(override, checkpoint)
tag_id = override.fetch(:set_id) { raise Checkpoints::SetIdRequiredError, "set_id is required, but was not provided" }
checkpoint.course.differentiation_tags.where(id: tag_id).first
end
private
def differentiation_tags_enabled_for_context?(checkpoint)
account = checkpoint.course.account
account.allow_assign_to_differentiation_tags?
end
end
View on GitHub (pinned to 1c9f0bb801)