instructure/canvas-lms · error · Checkpoints::GroupAssignmentRequiredError
must be a group assignment in order to create group…
Error message
must be a group assignment in order to create group overrides
What it means
Checkpoints::GroupAssignmentRequiredError raised in GroupOverrideUpdaterService#call when the checkpoint has no effective group category AND the override is not a differentiation-tag override. Updates to group overrides require the checkpoint to remain a group assignment; the exception names 'create' because it shares the message with the creator.
Solutions
- Restore a group category on the checkpoint/parent assignment before updating group overrides
- Delete stale group overrides instead of updating them when the assignment became individual
- Ensure differentiation-tag detection data (tags enabled for context, correct set_id) so the tag path is taken when intended
- Rescue Checkpoints::GroupAssignmentRequiredError and return 422
Example fix
// before
Checkpoints::GroupOverrideUpdaterService.new(individual_checkpoint, { id: id, set_id: gid }).call
// after
return unless checkpoint.effective_group_category_id.present?
Checkpoints::GroupOverrideUpdaterService.new(checkpoint, { id: id, set_id: gid }).call Defensive patterns
Strategy: validation
Validate before calling
if checkpoint.effective_group_category_id.nil?
return render json: { error: 'not a group assignment' }, status: :unprocessable_entity
end
Checkpoints::GroupOverrideUpdaterService.new(checkpoint, override).call Type guard
def updatable_group_override?(checkpoint, override) checkpoint.effective_group_category_id.present? || override[:set_id].present? end
Try / catch
begin Checkpoints::GroupOverrideUpdaterService.new(checkpoint, override).call rescue Checkpoints::GroupAssignmentRequiredError head :unprocessable_entity end
Prevention
- Delete stale group overrides when assignment submission type changes
- Gate update endpoints on checkpoint group-assignment state
- Keep parent assignment group category in sync with checkpoints
When it happens
Trigger: Calling the updater with a group-set override payload for a checkpoint whose effective_group_category_id is nil and whose payload is not tagged as a differentiation-tag override (e.g. set_id points to a tag but differentiation tag path not detected).
Common situations: Assignment reverted from group to individual while old group overrides still exist and get updated; client updates an override whose set_type no longer matches the checkpoint's submission type.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- must be a group assignment in order to create group…
- Can't update submission scores unless it's completed
- set_id is required, but was not provided
- set_id is required, but was not provided
- set_id is required, but was not provided
AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15).
Data as JSON: /api/errors/714fb98e4401744a.
Report an issue: GitHub.
Appendix: source
Thrown at app/services/checkpoints/group_override_updater_service.rb:33
# details.
#
# 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::GroupOverrideUpdaterService < ApplicationService
include Checkpoints::DateOverrider
include Checkpoints::GroupOverrideCommon
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
View on GitHub (pinned to 1c9f0bb801)