instructure/canvas-lms · error · ImportError

Only one context is allowed and both course_id and…

Error message

Only one context is allowed and both course_id and account_id where provided for group #{group_id}.

What it means

Raised in add_group when both course_id and account_id are supplied for the same group row. A SIS group must belong to exactly one context, so specifying both is contradictory and rejected immediately after the basic field checks. The message contains a known typo ('where' for 'were').

Solutions

  1. Remove one value — keep course_id for course groups, account_id for account groups.
  2. Configure the CSV generator to emit only the applicable context column.
  3. Split the file into account-scoped and course-scoped rows.
  4. Pre-validate the row: reject if both are present.

Example fix

# before
group_id,account_id,course_id,name,status
G101,A100,C200,Study Group A,available
# after
group_id,course_id,name,status
G101,C200,Study Group A,available
Defensive patterns

Strategy: validation

Validate before calling

raise ArgumentError, 'provide either account_id or course_id, not both' if account_id.present? && course_id.present?

Try / catch

begin
  importer.add_group(gid, cat_id, acct_id, course_id, name, status)
rescue ImportError => e
  logger.warn("Conflicting context columns: #{e.message}")
end

Prevention

When it happens

Trigger: A groups row or programmatic add_group call that populates both the account_id and course_id values for one group_id.

Common situations: Generators that always emit both columns; merged exports from two sources; template rows pre-filled with example ids; copy/paste errors.

Related errors


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

Appendix: source

Thrown at lib/sis/group_importer.rb:159

        same_context = new_context.id == item.context_id &&
                       new_context.class.base_class.name == item.context_type

        # For groups, we only block moves between courses, but allow other context changes
        if !same_context &&
           ((item.context.is_a?(Course) || new_context.is_a?(Course)) || item_type == "differentiation_tag")
          raise ImportError, "Cannot move #{type_display_name(item_type)} #{item_id} because it has #{item_type}_memberships."
        end

        true
      end

      public

      def add_group(group_id, group_category_id, account_id, course_id, name, status)
        return if invalid_import_item?(group_id, name, status, "group")

        if course_id && account_id
          raise ImportError, "Only one context is allowed and both course_id and account_id where provided for group #{group_id}."
        end

        context = find_context(account_id, :account_id, "group", group_id) if account_id
        context ||= find_context(course_id, :course_id, "group", group_id) if course_id

        group_category = nil
        if group_category_id.present?
          group_category = find_category(group_category_id, context, :group_category, "group", group_id)
        end

        group = @root_account.all_groups.find_by(sis_source_id: group_id)

        if group_category
          context = group_category.context
          if group
            group.group_category = group_category
          else
            group = group_category.groups.new(name:, sis_source_id: group_id)

View on GitHub (pinned to 1c9f0bb801)