instructure/canvas-lms · error · ImportError

No course_id or section_id given for an enrollment

Error message

No course_id or section_id given for an enrollment

What it means

SIS::Models::Enrollment objects must reference a course or a section; EnrollmentImporter.add_enrollment raises ImportError when `enrollment.valid_context?` is false, i.e. both course_id and section_id are missing/blank. The importer cannot know where to enroll the user without a context.

Solutions

  1. Fix the enrollments CSV so each row has a valid course_id (or section_id) column value
  2. Verify CSV headers match what the parser expects so course_id/section_id are populated
  3. For programmatic use, construct the Enrollment with `course_id:` or `section_id:` set to a valid SIS id

Example fix

// before
SIS::Models::Enrollment.new(course_id: nil, section_id: nil, user_id: 'u1', status: 'active')
// after
SIS::Models::Enrollment.new(section_id: 'sec-1', user_id: 'u1', status: 'active')
Defensive patterns

Strategy: validation

Validate before calling

raise 'enrollment needs course_id or section_id' if enrollment.course_id.blank? && enrollment.section_id.blank?

Type guard

def valid_context?(enrollment)
  enrollment.course_id.present? || enrollment.section_id.present?
end

Try / catch

begin
  importer.add_enrollment(enrollment)
rescue SIS::Base::ImportError => e
  logger.warn("Skipping enrollment: #{e.message}")
end

Prevention

When it happens

Trigger: Calling `add_enrollment(enrollment)` (or the CSV import path that feeds it) with an Enrollment whose course_id and section_id are both nil/blank, e.g. a malformed enrollments CSV row missing the section_id and course_id columns.

Common situations: Enrollments CSV with wrong header names so course_id/section_id are never parsed; rows referencing only a course short name that fails to resolve; hand-built Enrollment objects in scripts that forget to set either 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


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

Appendix: source

Thrown at lib/sis/enrollment_importer.rb:133

        @incrementally_update_account_associations_user_ids = Set.new
        @users_to_touch_ids = Set.new
        @courses_to_touch_ids = Set.new
        @courses_to_recache_due_dates = {}
        @enrollments_to_add_to_favorites = []
        @enrollments_to_update_sis_batch_ids = []
        @roll_back_data = []
        @enrollments_to_delete = []
        @account_chain_cache = {}
        @course = @section = nil
        @course_roles_by_account_id = {}

        @enrollment_batch = []
        @success_count = 0
      end

      # Pass a single instance of SIS::Models::Enrollment
      def add_enrollment(enrollment)
        raise ImportError, "No course_id or section_id given for an enrollment" unless enrollment.valid_context?
        raise ImportError, "No user_id given for an enrollment" unless enrollment.valid_user?
        raise ImportError, "Improper status \"#{enrollment.status}\" for an enrollment" unless enrollment.valid_status?
        return if @batch.skip_deletes? && enrollment.status =~ /deleted/i

        @enrollment_batch << enrollment
        process_batch if @enrollment_batch.size >= BATCH_SIZE
      end

      def any_left_to_process?
        !@enrollment_batch.empty?
      end

      def process_batch
        return unless any_left_to_process?

        enrollment_info = nil
        until @enrollment_batch.empty?
          enrollment_info = @enrollment_batch.shift

View on GitHub (pinned to 1c9f0bb801)