instructure/canvas-lms · error
unsupported migration type
Error message
unsupported migration type
What it means
selective_content_formatter#get_content_list serves the list of migratable items per content type (assignments, quizzes, modules, etc.). It raises 'unsupported migration type' when the requested type is neither one of SELECTIVE_CONTENT_TYPES, nor a 'submodules_'/'learning_outcome_groups_' prefixed type, nor nil.
Solutions
- Check SELECTIVE_CONTENT_TYPES in selective_content_formatter.rb for the accepted type strings
- Fix the caller to pass one of the supported types (or omit type for all)
- Add the new type to SELECTIVE_CONTENT_TYPES if it is a legitimately new content category
- Guard API clients against version skew by validating types against the course migration's available types
Example fix
// before
formatter.get_content_list("wiki_pages_old")
// after
formatter.get_content_list("wiki_pages") Defensive patterns
Strategy: validation
Validate before calling
SELECTIVE_CONTENT_TYPES = %w[assignments quizzes modules files pages discussions announcements].freeze raise 'bad type' unless type.nil? || SELECTIVE_CONTENT_TYPES.include?(type)
Type guard
def supported_type?(t)
t.nil? || SELECTIVE_CONTENT_TYPES.include?(t) || t.start_with?('submodules_', 'learning_outcome_groups_')
end Try / catch
begin
formatter.get_content_list(type)
rescue RuntimeError => e
raise unless e.message == 'unsupported migration type'
render json: {error: 'unsupported type'}, status: :bad_request
end Prevention
- Derive API-allowed types from SELECTIVE_CONTENT_TYPES, not hardcoded lists
- Keep frontend type names in sync with backend via shared constant/contract tests
- Reject unknown types at the controller layer with a clear message
When it happens
Trigger: Calling get_content_list('unknown_type') (optionally with source) on a SelectiveContentFormatter where valid_type? returns false — e.g. an arbitrary type string from an API client or a typo'd content type.
Common situations: Frontend/API sending a content type the backend version doesn't know (version skew); new content types added in one layer but not to SELECTIVE_CONTENT_TYPES; hand-crafted API requests.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- Cannot validate existence for resource type: #
- Course not found
- Embed not found for resource type: #
- Embed not found in scan for resource: #
- Invalid resource group key: #
AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15).
Data as JSON: /api/errors/1302e97b46aa4dba.
Report an issue: GitHub.
Appendix: source
Thrown at lib/canvas/migration/helpers/selective_content_formatter.rb:54
["calendar_events", -> { I18n.t("lib.canvas.migration.calendar_events", "Calendar Events") }],
["rubrics", -> { I18n.t("lib.canvas.migration.rubrics", "Rubrics") }],
["groups", -> { I18n.t("lib.canvas.migration.groups", "Student Groups") }],
["learning_outcomes", -> { I18n.t("lib.canvas.migration.learning_outcomes", "Learning Outcomes") }],
["attachments", -> { I18n.t("lib.canvas.migration.attachments", "Files") }],
].freeze
def initialize(migration = nil, base_url = nil, global_identifiers:)
@migration = migration
@base_url = base_url
@global_identifiers = global_identifiers
end
def valid_type?(type = nil)
type.nil? || SELECTIVE_CONTENT_TYPES.any? { |t| t[0] == type } || type.start_with?("submodules_") || type.start_with?("learning_outcome_groups_")
end
def get_content_list(type = nil, source = nil)
raise "unsupported migration type" unless valid_type?(type)
if !@migration || @migration.migration_type == "course_copy_importer"
get_content_from_course(type, source)
elsif @migration.overview_attachment
get_content_from_overview(type)
else
raise "course hasn't been converted"
end
end
private
def property_prefix
@migration ? "copy" : "select"
end
# pulls the available items from the overview attachment on the content migration
def get_content_from_overview(type = nil)View on GitHub (pinned to 1c9f0bb801)