instructure/canvas-lms · error · ArgumentError

Group category IDs do not match

Error message

Group category IDs do not match

What it means

validate_and_remove_group_category_id raises ArgumentError "Group category IDs do not match" when assignment_params[:group_category_id] is present, the discussion topic already has a group_category_id, and the two differ (string-vs-integer compared via to_s). resolve wraps this into a user-facing ExecutionError; it guards against silently re-pointing a group discussion's assignment at a different group set.

Solutions

  1. Send the topic's current group_category_id (as string) in the assignment params, or omit it.
  2. Remove/recreate the assignment separately if the group set genuinely must change.
  3. Delete the topic's group_category_id first (convert to non-group discussion), then re-add with the new group set and assignment.
  4. Normalize both IDs to strings before comparing if you hit this in modified code.

Example fix

// before
if assignment_params[:group_category_id] != discussion_topic.group_category_id.to_s
  raise ArgumentError, "Group category IDs do not match"
end
// after
if assignment_params[:group_category_id].to_s != discussion_topic.group_category_id.to_s
  raise ArgumentError, "Group category IDs do not match"
end
Defensive patterns

Strategy: validation

Validate before calling

const topicGcid = discussionTopic.group_category_id&.to_s
if assignment_params[:group_category_id].present? && topicGcid.present? && assignment_params[:group_category_id].to_s != topicGcid
  raise ArgumentError, 'Group category IDs do not match'
end

Type guard

function sameGroupCategory(a, b) { return a == null || b == null || String(a) === String(b); }

Try / catch

begin
  update_topic_with_assignment(params)
rescue ArgumentError => e
  raise GraphQL::ExecutionError, e.message if e.message.include?('Group category')
  raise
end

Prevention

When it happens

Trigger: set_discussion_assignment_association -> validate_and_remove_group_category_id during updateDiscussionTopic when the assignment input carries a groupCategoryId different from the topic's; also triggered by type mismatch ("5" vs 5 style comparisons if to_s were omitted elsewhere) though here to_s normalizes.

Common situations: Instructor changes group set on a group discussion that already has an assignment; external tools syncing assignments with their own group category; scripted migrations copying assignment payloads between topics.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

Thrown at app/graphql/mutations/update_discussion_topic.rb:287

    validate_and_remove_group_category_id(assignment_params, discussion_topic) if assignment_params.key?(:group_category_id)

    # If a topic doesn't have a group_category_id or has submissions, then the assignment group_category_id should be nil
    unless discussion_topic.try(:group_category_id) || assignment.has_submitted_submissions?
      assignment_params[:group_category_id] = nil
    end

    # Finalize assignment restoration
    discussion_topic.assignment = assignment
    discussion_topic.sync_assignment
    # This save is required to prevent an extra discussion_topic from being created in the updateAssignment
    assignment.updating_user = current_user
    assignment.save!
  end
end

def validate_and_remove_group_category_id(assignment_params, discussion_topic)
  if assignment_params[:group_category_id].present? && discussion_topic.group_category_id.present? && assignment_params[:group_category_id] != discussion_topic.group_category_id.to_s
    raise ArgumentError, "Group category IDs do not match"
  end

  if assignment_params[:group_category_id].present?
    assignment_params.delete(:group_category_id)
  end
end

View on GitHub (pinned to 1c9f0bb801)