{"record":{"id":"3e2f092ba367a64a","repo":"instructure/canvas-lms","slug":"improper-status-status-for-a-cross-listing-xlist-importer","errorCode":null,"errorMessage":"Improper status #{status} for a cross-listing","messagePattern":"Improper status #(.+?) for a cross-listing","errorType":"validation","errorClass":"ImportError","httpStatus":null,"severity":"warning","filePath":"lib/sis/xlist_importer.rb","lineNumber":121,"sourceCode":"            rescue => e\n              raise ImportError, \"An active cross-listing failed: #{e}\"\n            end\n\n          when /\\Adeleted\\z/i\n            if @course && section.course_id != @course.id\n              @success_count += 1\n              return\n            end\n\n            begin\n              @course_ids_to_update_associations.merge [section.course_id, section.nonxlist_course_id]\n              section.uncrosslist(run_jobs_immediately: true)\n            rescue => e\n              raise ImportError, \"A deleted cross-listing failed: #{e}\"\n            end\n\n          else\n            raise ImportError, \"Improper status #{status} for a cross-listing\"\n          end\n\n          @success_count += 1\n        end\n      end\n    end\n  end\nend\n","sourceCodeStart":103,"sourceCodeEnd":130,"githubUrl":"https://github.com/instructure/canvas-lms/blob/1c9f0bb8013ed69c4f2efe11fd483025469b7e6c/lib/sis/xlist_importer.rb#L103-L130","documentation":"A defensive fallback inside add_crosslist's case statement: if status matched neither the 'active' nor 'deleted' branch, ImportError \"Improper status ... for a cross-listing\" is raised. With the current regex this is largely unreachable, but it guards the case-statement against future status values added without corresponding branches.","triggerScenarios":"A code change introduces a new accepted status in the line-55 regex (or bypasses it) but no case branch handles it; a caller monkey-patching or refactoring the validation lets an unexpected status through to the case statement.","commonSituations":"Custom Canvas patches/plugins extending cross-listing statuses; refactors that decouple the upfront regex validation from the case dispatch.","solutions":["Keep the regex at line 55 and the case statement branches in sync when adding statuses","Add an explicit branch (or explicit rejection) for any new status value","Rely on the line-55 validation: ensure status is 'active' or 'deleted' before calling add_crosslist","Remove custom patches that inject third status values"],"exampleFix":"# before\ncase status\nwhen /\\Aactive\\z/i then ...\nwhen /\\Adeleted\\z/i then ...\nelse raise\nend\n# after\nunless status =~ /\\A(active|deleted)\\z/i\n  raise ImportError, \"Improper status #{status.inspect} for a cross-listing\"\nend\ncase status\nwhen /\\Aactive\\z/i then ...\nwhen /\\Adeleted\\z/i then ...\nend","handlingStrategy":"validation","validationCode":"raise ArgumentError, 'status must be active or deleted' unless status.to_s.match?(/\\A(active|deleted)\\z/i)","typeGuard":null,"tryCatchPattern":"begin\n  xlist.add_crosslist(xlist_course_id, section_id, status)\nrescue SIS::ImportError => e\n  Rails.logger.warn(\"Crosslist rejected: #{e.message}\")\nend","preventionTips":["Keep the validation regex and case branches in sync when extending statuses","Avoid custom patches introducing extra status values","Cover add_crosslist with specs for each accepted status"],"tags":["sis","import","invalid-enum-value","invariant"],"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"}