{"record":{"id":"c924c036ba8a9545","repo":"instructure/canvas-lms","slug":"no-course-id-or-section-id-given-for-an-enrollment","errorCode":null,"errorMessage":"No course_id or section_id given for an enrollment","messagePattern":"No course_id or section_id given for an enrollment","errorType":"exception","errorClass":"ImportError","httpStatus":null,"severity":"error","filePath":"lib/sis/enrollment_importer.rb","lineNumber":133,"sourceCode":"        @incrementally_update_account_associations_user_ids = Set.new\n        @users_to_touch_ids = Set.new\n        @courses_to_touch_ids = Set.new\n        @courses_to_recache_due_dates = {}\n        @enrollments_to_add_to_favorites = []\n        @enrollments_to_update_sis_batch_ids = []\n        @roll_back_data = []\n        @enrollments_to_delete = []\n        @account_chain_cache = {}\n        @course = @section = nil\n        @course_roles_by_account_id = {}\n\n        @enrollment_batch = []\n        @success_count = 0\n      end\n\n      # Pass a single instance of SIS::Models::Enrollment\n      def add_enrollment(enrollment)\n        raise ImportError, \"No course_id or section_id given for an enrollment\" unless enrollment.valid_context?\n        raise ImportError, \"No user_id given for an enrollment\" unless enrollment.valid_user?\n        raise ImportError, \"Improper status \\\"#{enrollment.status}\\\" for an enrollment\" unless enrollment.valid_status?\n        return if @batch.skip_deletes? && enrollment.status =~ /deleted/i\n\n        @enrollment_batch << enrollment\n        process_batch if @enrollment_batch.size >= BATCH_SIZE\n      end\n\n      def any_left_to_process?\n        !@enrollment_batch.empty?\n      end\n\n      def process_batch\n        return unless any_left_to_process?\n\n        enrollment_info = nil\n        until @enrollment_batch.empty?\n          enrollment_info = @enrollment_batch.shift","sourceCodeStart":115,"sourceCodeEnd":151,"githubUrl":"https://github.com/instructure/canvas-lms/blob/1c9f0bb8013ed69c4f2efe11fd483025469b7e6c/lib/sis/enrollment_importer.rb#L115-L151","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Fix the enrollments CSV so each row has a valid course_id (or section_id) column value","Verify CSV headers match what the parser expects so course_id/section_id are populated","For programmatic use, construct the Enrollment with `course_id:` or `section_id:` set to a valid SIS id"],"exampleFix":"// before\nSIS::Models::Enrollment.new(course_id: nil, section_id: nil, user_id: 'u1', status: 'active')\n// after\nSIS::Models::Enrollment.new(section_id: 'sec-1', user_id: 'u1', status: 'active')","handlingStrategy":"validation","validationCode":"raise 'enrollment needs course_id or section_id' if enrollment.course_id.blank? && enrollment.section_id.blank?","typeGuard":"def valid_context?(enrollment)\n  enrollment.course_id.present? || enrollment.section_id.present?\nend","tryCatchPattern":"begin\n  importer.add_enrollment(enrollment)\nrescue SIS::Base::ImportError => e\n  logger.warn(\"Skipping enrollment: #{e.message}\")\nend","preventionTips":["Validate CSV headers match the expected enrollments schema","Require course_id or section_id in every row before import","Unit-test CSV parsing with a sample enrollments file"],"tags":["ruby","sis-import","enrollment","missing-identifier"],"backgroundTag":"missing-required-argument","analyzedSha":"1c9f0bb8013ed69c4f2efe11fd483025469b7e6c","analyzedAt":"2026-09-15T20:33:18.891Z","contentChangedAt":"2026-09-15T20:33:18.891Z","schemaVersion":2},"datasetVersion":"2026-09-23T02:17:17.105Z"}