instructure/canvas-lms · error · GraphQL::ExecutionError

Assignment group category id and discussion topic group…

Error message

Assignment group category id and discussion topic group category id do not match

What it means

UpdateDiscussionTopic#resolve rescues ArgumentError raised deeper in the assignment/group-category handling (see validate_and_remove_group_category_id) and re-raises it as GraphQL::ExecutionError with the message "Assignment group category id and discussion topic group category id do not match". It signals an attempt to attach an assignment whose group set differs from the topic's group set.

Solutions

  1. Align the payload's group_category_id with the topic's existing group_category_id, or clear the topic's group set first.
  2. Split into two mutations: first update the topic's group set, then update the assignment.
  3. Omit group_category_id from the assignment input when it should inherit the topic's group set.
  4. Validate ids client-side against the topic's groupSet before submit.

Example fix

// before
updateDiscussionTopic(input: {id: t, assignment: {groupCategoryId: "42"}})
// after
updateDiscussionTopic(input: {id: t, assignment: {groupCategoryId: topic.groupSet.id}})
Defensive patterns

Strategy: validation

Validate before calling

if (input.assignment?.groupCategoryId && topic.groupSet && input.assignment.groupCategoryId !== topic.groupSet.id) {
  throw new Error('Group category must match the topic group set');
}

Type guard

function groupCategoriesMatch(assignmentInput, topic) {
  return !assignmentInput.groupCategoryId || String(assignmentInput.groupCategoryId) === String(topic.groupCategoryId);
}

Try / catch

try {
  await updateDiscussionTopic(...);
} catch (e) {
  if (e.message.includes('group category id')) {
    // resync group set then retry
    await updateTopicGroupSet();
    await updateDiscussionTopic(...);
  }
}

Prevention

When it happens

Trigger: Passing assignment: {groupCategoryId: X} in updateDiscussionTopic where the topic already has group_category_id Y != X, e.g. switching a group discussion's group set while also creating/updating its assignment in one call.

Common situations: Instructors moving a discussion to a different student group set; LTI tools submitting assignment payloads with a default group category; import/migration reusing stale group_category_id values; frontend form caching the old group set after topic edit.

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/defd50001ac25851. Report an issue: GitHub.

Appendix: source

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

    end

    discussion_topic.editor = current_user
    return errors_for(discussion_topic) unless discussion_topic.save!

    if input.key?(:ungraded_discussion_overrides)
      overrides = input[:ungraded_discussion_overrides] || []
      update_ungraded_discussion(discussion_topic, overrides)
    end

    discussion_topic.assignment = assignment_result[:assignment] if assignment_result && assignment_result[:assignment]

    {
      discussion_topic:
    }
  rescue ActiveRecord::RecordNotFound
    raise GraphQL::ExecutionError, "not found"
  rescue ArgumentError
    raise GraphQL::ExecutionError, "Assignment group category id and discussion topic group category id do not match"
  end
end

def set_discussion_assignment_association(assignment_params, discussion_topic)
  # Determine if the assignment is being deleted
  is_deleting_assignment = assignment_params.key?(:set_assignment) && !assignment_params[:set_assignment]

  if is_deleting_assignment && !discussion_topic&.assignment.nil?
    assignment = discussion_topic.assignment

    if assignment.has_sub_assignments
      Checkpoints::DiscussionCheckpointDeleterService.call(
        discussion_topic:
      )
    end

    discussion_topic.assignment = nil
    assignment.discussion_topic = nil

View on GitHub (pinned to 1c9f0bb801)