{"record":{"id":"230b93472e26146e","repo":"instructure/canvas-lms","slug":"invalid-grade-passback-setting-grade-passback-setting-for","errorCode":null,"errorMessage":"Invalid grade_passback_setting \"#{grade_passback_setting}\" for course #{course_id}","messagePattern":"Invalid grade_passback_setting \"#(.+?)\" for course #(.+?)","errorType":"exception","errorClass":"ImportError","httpStatus":null,"severity":"error","filePath":"lib/sis/course_importer.rb","lineNumber":73,"sourceCode":"        @courses_to_update_sis_batch_id = a1\n        @course_ids_to_update_associations = a2\n        @roll_back_data = []\n        @blueprint_associations = blueprint_associations\n        @messages = m\n        @logger = logger\n        @success_count = 0\n      end\n\n      def add_course(course_id, term_id, account_id, fallback_account_id, status, start_date, end_date, abstract_course_id, short_name, long_name, integration_id, course_format, blueprint_course_id, grade_passback_setting, homeroom_course, friendly_name)\n        state_changes = []\n        raise ImportError, \"No course_id given for a course\" if course_id.blank?\n        raise ImportError, \"No short_name given for course #{course_id}\" if short_name.blank? && abstract_course_id.blank?\n        raise ImportError, \"No long_name given for course #{course_id}\" if long_name.blank? && abstract_course_id.blank?\n        raise ImportError, \"Improper status \\\"#{status}\\\" for course #{course_id}\" unless /\\A(active|deleted|completed|unpublished|published)/i.match?(status)\n        raise ImportError, \"Invalid course_format \\\"#{course_format}\\\" for course #{course_id}\" unless course_format.blank? || course_format =~ /\\A(online|on_campus|blended|not_set)/i\n\n        valid_grade_passback_settings = %w[nightly_sync disabled not_set]\n        raise ImportError, \"Invalid grade_passback_setting \\\"#{grade_passback_setting}\\\" for course #{course_id}\" unless grade_passback_setting.blank? || valid_grade_passback_settings.include?(grade_passback_setting.downcase.strip)\n        return if @batch.skip_deletes? && status =~ /deleted/i\n\n        Course.unique_constraint_retry do\n          course = @root_account.all_courses.find_by(sis_source_id: course_id)\n          if course.nil?\n            course = Course.new\n            state_changes << :created\n          else\n            state_changes << :updated\n          end\n          course.saved_by = :sis_import\n          course_enrollment_term_id_stuck = course.stuck_sis_fields.include?(:enrollment_term_id)\n          if !course_enrollment_term_id_stuck && term_id\n            term = @root_account.enrollment_terms.active.find_by(sis_source_id: term_id)\n          end\n          course.enrollment_term = term if term\n          course.root_account = @root_account\n","sourceCodeStart":55,"sourceCodeEnd":91,"githubUrl":"https://github.com/instructure/canvas-lms/blob/1c9f0bb8013ed69c4f2efe11fd483025469b7e6c/lib/sis/course_importer.rb#L55-L91","documentation":"SisCourseImporter#add_course raises ImportError when grade_passback_setting is non-blank and its downcased/stripped value is not in [nightly_sync, disabled, not_set]. This optional column controls the course's gradebook pass-back behavior and must use a recognized value.","triggerScenarios":"add_course called with grade_passback_setting like \"enabled\", \"sync\", \"on\", \"nightly\" — anything outside the three-value list after downcase+strip. Note: unlike status/format checks, this one strips and downcases first, so \"Nightly_Sync \" is fine but \"enabled\" is not.","commonSituations":"Feeds exporting \"enabled\"/\"disabled\" boolean-ish wording (\"enabled\" is invalid; the valid inverse is \"disabled\"); older SIS files written before the setting existed using different vocabulary; docs confusion between \"nightly_sync\" and \"nightly\".","solutions":["Use one of exactly: nightly_sync, disabled, not_set (case/whitespace are normalized for you)","Replace \"enabled\" with \"nightly_sync\" — the most common near-miss value","Leave the column blank if the course should keep its default behavior","Add pre-import normalization mapping synonyms (on/off/enabled/none) to the three valid values"],"exampleFix":"// before\npassback = \"enabled\"\n// after\npassback = {\"enabled\"=>\"nightly_sync\", \"on\"=>\"nightly_sync\", \"off\"=>\"disabled\", \"none\"=>\"not_set\"}.fetch(passback.to_s.strip.downcase, passback)","handlingStrategy":"validation","validationCode":"gp = row['grade_passback_setting'].to_s.strip.downcase\nraise ArgumentError, \"bad grade_passback_setting\" unless gp.empty? || %w[nightly_sync disabled not_set].include?(gp)","typeGuard":"def valid_passback?(v) = v.to_s.strip.empty? || %w[nightly_sync disabled not_set].include?(v.to_s.strip.downcase)","tryCatchPattern":"begin\n  importer.add_course(...)\nrescue SisImport::ImportError => e\n  raise unless e.message.start_with?('Invalid grade_passback_setting')\n  log.warn(\"fixing grade_passback_setting for course: #{e.message}\")\nend","preventionTips":["Remember 'enabled' is NOT valid — the positive value is 'nightly_sync'","Normalize synonyms (on/off/enabled) to the three valid values in the exporter","Leave the column blank for default behavior","Add enum validation to the CSV lint step"],"tags":["sis-import","invalid-enum","course-import"],"backgroundTag":"invalid-enum-value","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"}