{"record":{"id":"99f06aeeaeab9987","repo":"instructure/canvas-lms","slug":"cannot-restore-course-course-id-because-the-associated","errorCode":null,"errorMessage":"Cannot restore course #{course_id} because the associated account #{course.account.sis_source_id} is deleted","messagePattern":"Cannot restore course #(.+?) because the associated account #(.+?) is deleted","errorType":"exception","errorClass":"ImportError","httpStatus":null,"severity":"error","filePath":"lib/sis/course_importer.rb","lineNumber":105,"sourceCode":"            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\n          account = nil\n          account = @root_account.all_accounts.find_by(sis_source_id: account_id) if account_id.present?\n          account ||= @root_account.all_accounts.find_by(sis_source_id: fallback_account_id) if fallback_account_id.present?\n          if account_id.present? && !account\n            raise ImportError, \"Account not found \\\"#{account_id}\\\" for course #{course_id}\"\n          end\n\n          course_account_stuck = course.stuck_sis_fields.include?(:account_id)\n          if !course_account_stuck && account&.active?\n            course.account = account\n          end\n\n          if course.account&.deleted?\n            raise ImportError, \"Cannot restore course #{course_id} because the associated account #{course.account.sis_source_id} is deleted\"\n          end\n\n          course.account ||= @root_account\n\n          update_account_associations = course.account_id_changed? || course.root_account_id_changed?\n\n          if account&.enable_as_k5_account? && friendly_name.present?\n            course.friendly_name = friendly_name\n          end\n\n          course.integration_id = integration_id if integration_id.present?\n          course.sis_source_id = course_id\n          active_state = status.casecmp?(\"published\") ? \"available\" : \"claimed\"\n          unless course.stuck_sis_fields.include?(:workflow_state)\n            if %w[active unpublished published].include?(status.downcase)\n              case course.workflow_state\n              when \"completed\"\n                # not using active state here, because it has always been set to available","sourceCodeStart":87,"sourceCodeEnd":123,"githubUrl":"https://github.com/instructure/canvas-lms/blob/1c9f0bb8013ed69c4f2efe11fd483025469b7e6c/lib/sis/course_importer.rb#L87-L123","documentation":"SisCourseImporter#add_course raises ImportError when the course's associated account has been deleted (course.account&.deleted?). This blocks restoring/undeleting a course into a dead account, since a course cannot live under a deleted account. The message includes the offending account's sis_source_id.","triggerScenarios":"Re-importing (restoring) a previously deleted course whose account_id is stuck (stuck_sis_fields includes :account_id, so account reassignment is skipped) while that stored account is now deleted. Also triggered when the resolved/matched account was soft-deleted between imports.","commonSituations":"Account was deleted in a prior SIS run but course rows referencing it came back; the course row is processed for restore (status active/published) while its account is gone; workflow_state transitions on the account outside SIS control.","solutions":["Re-activate (restore) the deleted account in accounts.csv (status: active) before re-importing the course","Point the course at a live account by changing its account_id in courses.csv — note this requires account_id not be stuck; clear stuck sis fields if needed","Move the course to the root account or another active subaccount in the source SIS export","If the account deletion was a mistake, undo it in Canvas (rails console) before rerunning the batch"],"exampleFix":"// before (accounts.csv): the course's account stays deleted while course row says active\n\"acc-eng\",\"Engineering\",deleted\n// after\n\"acc-eng\",\"Engineering\",active","handlingStrategy":"validation","validationCode":"acct = course.account\nif course.persisted? && acct&.deleted?\n  raise ArgumentError, \"course #{course.sis_source_id} points at deleted account #{acct.sis_source_id}\"\nend","typeGuard":"def restorable_account?(course) = course.account.nil? || course.account.active?","tryCatchPattern":"begin\n  importer.add_course(...)\nrescue SisImport::ImportError => e\n  raise unless e.message.start_with?('Cannot restore course')\n  log.error(\"restore blocked by deleted account; restore the account first: #{e.message}\")\nend","preventionTips":["Restore or re-parent accounts before re-importing courses that reference them","Audit for deleted accounts still referenced by active course rows each cycle","Avoid deleting accounts that still have courses; move courses first","Clear stuck sis_fields on account_id when you intentionally reassign a course's account"],"tags":["sis-import","deleted-account","invalid-state"],"backgroundTag":"invalid-state-transition","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"}