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 in GroupOverrideUpdaterService#call via get_group_from_override/get_differentiation_tag_from_override (the shared common module) when the override hash lacks :set_id. Unlike 514, this fires when the fetch(:set_id) call itself misses the key, i.e. the payload key is entirely absent.
Solutions
- Always include set_id in override payloads sent to the updater service
- Merge the persisted override's set_id into the payload before calling the service
- Update older clients from group_id to set_id key naming
- Rescue Checkpoints::SetIdRequiredError at the API boundary and return 400
Example fix
// before
Checkpoints::GroupOverrideUpdaterService.new(checkpoint, { id: id, due_at: t }).call
// after
Checkpoints::GroupOverrideUpdaterService.new(checkpoint, { id: id, set_id: override.set_id, due_at: t }).call Defensive patterns
Strategy: validation
Validate before calling
payload = { id: override_id }.merge(override_payload)
payload[:set_id] ||= checkpoint.assignment_overrides.find(override_id).set_id
Checkpoints::GroupOverrideUpdaterService.new(checkpoint, payload).call Type guard
def override_payload_complete?(payload) payload.is_a?(Hash) && payload.key?(:set_id) && payload[:set_id].present? end
Try / catch
begin
Checkpoints::GroupOverrideUpdaterService.new(checkpoint, payload).call
rescue Checkpoints::SetIdRequiredError => e
render json: { error: e.message.presence || 'set_id is required' }, status: :bad_request
end Prevention
- Never send partial override payloads without set_id
- Standardize on set_id naming in all client versions
- Validate payload keys against a whitelist schema in the controller
When it happens
Trigger: Updater's group_id fallback succeeded via override.set_id, but a downstream call re-fetches :set_id from the raw override hash with fetch(:set_id){raise}, and the original payload had no set_id key. Actually in flow, this triggers when the shared helpers are called with a hash missing :set_id.
Common situations: Client sends partial update payloads (id + due_at only) for differentiation-tag or group overrides; older API clients still sending group_id instead of 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
- 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/57404f6d820aa398.
Report an issue: GitHub.
Appendix: source
Thrown at app/services/checkpoints/group_override_updater_service.rb:41
def initialize(checkpoint:, override:)
super()
@checkpoint = checkpoint
@override = override
end
def call
is_differentiation_tag_override = differentiation_tag_override?(@override, @checkpoint)
if @checkpoint.effective_group_category_id.nil? && !is_differentiation_tag_override
raise Checkpoints::GroupAssignmentRequiredError, "must be a group assignment in order to create group overrides"
end
override = @checkpoint.assignment_overrides.find_by(id: @override[:id], set_type: AssignmentOverride::SET_TYPE_GROUP)
raise Checkpoints::OverrideNotFoundError unless override
group_id = @override.fetch(:set_id, nil) || override.set_id
raise Checkpoints::SetIdRequiredError, "set_id is required, but was not provided" if group_id.blank?
group = is_differentiation_tag_override ? get_differentiation_tag_from_override(@override, @checkpoint) : get_group_from_override(@override, @checkpoint)
current_group = override.set
update_override(override:, group:)
parent_override = @checkpoint.parent_assignment.active_assignment_overrides.find_by(set: current_group)
raise Checkpoints::OverrideNotFoundError unless parent_override
update_override(override: parent_override, group:, shell_override: true)
override
end
private
def update_override(override:, group:, shell_override: false)View on GitHub (pinned to 1c9f0bb801)