{"record":{"id":"6d220066f9390f6c","repo":"instructure/canvas-lms","slug":"a-course-did-not-pass-validation-course-course-id-short-name","errorCode":null,"errorMessage":"A course did not pass validation (course: #{course_id} / #{short_name}, error: #{course.errors.full_messages.join(\",\")})","messagePattern":"A course did not pass validation \\(course: #(.+?) / #(.+?), error: #(.+?)\\)","errorType":"exception","errorClass":"ImportError","httpStatus":null,"severity":"error","filePath":"lib/sis/course_importer.rb","lineNumber":257,"sourceCode":"              else\n                msg = \"A (templated) course did not pass validation \" \\\n                      \"(course: #{course_id} / #{short_name}, error: \" \\\n                      \"#{templated_course.errors.full_messages.join(\",\")})\"\n                raise ImportError, msg\n              end\n            end\n            course.sis_batch_id = @batch.id\n            if course.valid?\n              course_changes = course.changes\n              course.save_without_broadcasting!\n              auditor_state_changes(course, state_changes, course_changes)\n              data = SisBatchRollBackData.build_data(sis_batch: @batch, context: course)\n              @roll_back_data << data if data\n            else\n              msg = \"A course did not pass validation \" \\\n                    \"(course: #{course_id} / #{short_name}, error: \" \\\n                    \"#{course.errors.full_messages.join(\",\")})\"\n              raise ImportError, msg\n            end\n            @course_ids_to_update_associations.add(course.id) if update_account_associations\n          else\n            @courses_to_update_sis_batch_id << course.id\n          end\n\n          if blueprint_course_id && !course.deleted?\n            case blueprint_course_id\n            when \"dissociate\"\n              MasterCourses::ChildSubscription.active.find_by(child_course_id: course.id)&.destroy\n            else\n              @blueprint_associations[blueprint_course_id] ||= []\n              @blueprint_associations[blueprint_course_id] << course_id\n            end\n          end\n\n          enrollment_data = course.update_enrolled_users(sis_batch: @batch) if update_enrollments\n          course.update_enrollment_states_if_necessary","sourceCodeStart":239,"sourceCodeEnd":275,"githubUrl":"https://github.com/instructure/canvas-lms/blob/1c9f0bb8013ed69c4f2efe11fd483025469b7e6c/lib/sis/course_importer.rb#L239-L275","documentation":"SisCourseImporter#add_course raises ImportError when the course record itself fails ActiveRecord validation (course.valid? false) just before save_without_broadcasting!. This is the non-templated counterpart of the templated-course validation error; the embedded course.errors.full_messages list names the specific failing validations.","triggerScenarios":"add_course reaches the final save path and course.valid? fails — e.g. invalid start/end dates (end before start), name too long, enrollment term restrictions, account_id nil, or uniqueness/constraint issues surfaced as validation errors.","commonSituations":"CSV rows with malformed or reversed start/end dates; names exceeding length limits after export transformations; conflicting concurrent edits in the UI leaving the course in a state SIS changes cannot validate against; term or account references failing association validations.","solutions":["Parse the embedded errors.full_messages to find the exact failing attribute(s)","Correct the offending values in courses.csv (e.g. ensure end_date >= start_date, names within limits) and re-run the batch","Verify the course's term and account associations are valid and present under the root account","Check for concurrent UI modifications to the course that make SIS-applied values invalid; reconcile before re-import"],"exampleFix":"// before: errors include \"End date must be after the start date\"\nrow = {start_date: \"2026-05-31\", end_date: \"2026-01-01\"}\n// after\nrow = {start_date: \"2026-01-01\", end_date: \"2026-05-31\"}","handlingStrategy":"try-catch","validationCode":"msg = e.message\nif (errs = msg[/error: (.*)\\)$/, 1])\n  log.error(\"course validation failed: #{errs}\")\nend","typeGuard":"nil","tryCatchPattern":"begin\n  importer.add_course(...)\nrescue SisImport::ImportError => e\n  raise unless e.message.start_with?('A course did not pass validation')\n  sis_batch_errors.record(course_id, e.message) # includes errors.full_messages detail\nend","preventionTips":["Validate dates in the export (end_date >= start_date, parseable formats)","Enforce name/short_name length limits in the generator","Capture and review the embedded errors.full_messages after every failed batch","Reconcile concurrent UI edits before running SIS updates on the same courses"],"tags":["sis-import","validation","activerecord"],"backgroundTag":"schema-validation-failed","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"}