instructure/canvas-lms · warning
Migration warning: #
Error message
Migration warning: #{user_message}: #{opts.inspect} What it means
ContentMigration#add_warning records a non-fatal migration issue on the migration object and logs this warning line. The message interpolates the human-readable problem plus the opts hash, which often carries an exception or failing item info. It surfaces in the migration UI as a warning without stopping the import.
Solutions
- Read the opts in the log/migration issues to identify the exact failed item (file, link, or exception)
- Fix the source content (restore missing files/links) and re-run the migration
- If a custom importer passes an Exception positionally, migrate to opts[:exception] / opts[:error_html] hash form
- If warnings are spurious, trace which importer calls add_warning and adjust its pre-checks
Example fix
// before
migration.add_warning("file missing", some_exception) # deprecated positional arg
// after
migration.add_warning("file missing", exception: some_exception) Defensive patterns
Strategy: try-catch
Validate before calling
# pre-check referenced content before import
course.attachments.where(id: referenced_ids).missing.each do |a|
migration.add_warning("missing attachment #{a.name}")
end Try / catch
begin
import_step
rescue => e
migration.add_warning("step failed", exception: e)
end Prevention
- Pass exceptions via opts[:exception], never positionally
- Fix source content (missing files/links) before re-running migrations
- Review migration warnings in the UI after every course copy
- Keep custom importers updated to current add_warning API
When it happens
Trigger: Any migration step (attachment copy, missing content-link detection, importer callbacks) calls add_warning(message, opts) — e.g. an attachment failed to copy, a referenced file is missing, or a deprecated Exception argument was passed as the second parameter.
Common situations: Course copies where source files were deleted; broken links to missing wiki pages/quizzes; third-party importers passing exceptions via the deprecated two-arg form; locked/hidden files that cannot be copied.
Understand the failure class
Background: "is deprecated and will be removed" — deprecation warnings for old API names, keywords, and options, and how to migrate before the removal release — this error's family across 29 libraries.
Related errors
- The external Rubric couldn't be found for "#
- A partner ID is required to use Academic Benchmarks
- Child content tag was not found for #
- course hasn't been converted
- Do not look up MediaObjects by media_id - use the scope…
AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15).
Data as JSON: /api/errors/49a2bad33ee1833c.
Report an issue: GitHub.
Appendix: source
Thrown at app/models/content_migration.rb:321
mi.delete
else
mi.save!
end
mi
end
def add_todo(user_message, opts = {})
add_issue(user_message, :todo, opts)
end
def add_error(user_message, opts = {})
level = opts.fetch(:issue_level, :error)
add_issue(user_message, level, opts)
end
def add_warning(user_message, opts = {})
Rails.logger.warn("Migration warning: #{user_message}: #{opts.inspect}")
unless opts.is_a? Hash
# convert deprecated behavior to new
exception_or_info = opts
opts = {}
if exception_or_info.is_a?(Exception)
opts[:exception] = exception_or_info
else
opts[:error_message] = exception_or_info
end
end
add_issue(user_message, :warning, opts)
end
def add_unique_warning(key, warning, opts = {})
@added_warnings ||= Set.new
return if @added_warnings.include?(key) # only add it once
@added_warnings << keyView on GitHub (pinned to 1c9f0bb801)