instructure/canvas-lms · warning · MigrationRunningError
cannot start new migration while another one is running
Error message
cannot start new migration while another one is running
What it means
MasterCourses::MasterMigration.start_new_migration! checks master_template.active_migration_running?; if a migration is already in progress and opts[:retry_later] is not set, it raises MigrationRunningError with this message. Canvas allows only one active master-course migration per template at a time.
Solutions
- Pass retry_later: true so Canvas reschedules the migration in 10 minutes instead of raising.
- Wait for the current migration to finish before starting a new one (check master_template.active_migration_running?).
- If the active migration is genuinely stuck, clear the stale state (reset master_template.active_migration / inspect the delayed job) and retry.
- Debounce/dedupe UI or API triggers so concurrent sync requests don't pile up.
Example fix
// before MasterCourses::MasterMigration.start_new_migration!(template, user) // after MasterCourses::MasterMigration.start_new_migration!(template, user, retry_later: true)
Defensive patterns
Strategy: try-catch
Validate before calling
if template.active_migration_running? MasterCourses::MasterMigration.start_new_migration!(template, user, retry_later: true) else MasterCourses::MasterMigration.start_new_migration!(template, user) end
Try / catch
begin MasterCourses::MasterMigration.start_new_migration!(template, user) rescue MasterCourses::MasterMigration::MigrationRunningError # notify user a migration is already running; retry later end
Prevention
- Default to retry_later: true for automated/scheduled syncs
- Check active_migration_running? before exposing the sync button
- Monitor for stuck migrations and alert on templates with long-running active_migration
When it happens
Trigger: Calling start_new_migration! (or triggering an export/sync via API or UI) while the template's previous migration is still queued/running, without passing retry_later: true.
Common situations: Users clicking 'sync' repeatedly while a large migration runs; scheduled/automated sync jobs overlapping manual migrations; a stuck previous migration (failed delayed job) that never cleared active_migration, blocking all new ones.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Embed not found for resource type: #
- A new_id, '# ', referenced an existing # and the # with #…
- A new_integration_id, '#
- A student referenced a non-existent user #
- A user did not pass validation
AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15).
Data as JSON: /api/errors/5bf099b63ba9b5f1.
Report an issue: GitHub.
Appendix: source
Thrown at app/models/master_courses/master_migration.rb:76
state :completed # after all the imports have run (successfully hopefully)
state :exports_failed # if we break during export
state :imports_failed # if one or more of the imports failed
end
class MigrationRunningError < StandardError; end
# create a new migration and queue it up (if we can)
def self.start_new_migration!(master_template, user, opts = {})
master_template.class.transaction do
master_template.lock!
if master_template.active_migration_running?
if opts[:retry_later]
delay(singleton: "retry_start_master_migration_#{master_template.global_id}",
run_at: 10.minutes.from_now)
.start_new_migration!(master_template, user, opts)
else
raise MigrationRunningError, "cannot start new migration while another one is running"
end
else
new_migration = master_template.master_migrations.create!({ user: }.merge(opts.except(:retry_later, :priority)))
master_template.active_migration = new_migration
master_template.save!
new_migration.queue_export_job(priority: opts[:priority] || Delayed::LOW_PRIORITY)
new_migration
end
end
end
def copy_settings=(val)
migration_settings[:copy_settings] = val
end
def send_item_notifications=(val)
migration_settings[:send_item_notifications] = val
endView on GitHub (pinned to 1c9f0bb801)