instructure/canvas-lms · error · RuntimeError
Content Export for Outcomes Service failed
Error message
Content Export for Outcomes Service failed
What it means
export_completed? polls the outcomes service content_exports API. A 2xx response with json["state"] == 'failed' means the remote export job failed, so it raises 'Content Export for Outcomes Service failed'.
Solutions
- Check the outcomes service logs for the export id to find the remote failure cause
- Queue a new export via begin_export and retry the migration
- Fix any course/content data problems reported remotely before retrying
Defensive patterns
Strategy: try-catch
Try / catch
begin done = MigrationService.export_completed?(export_data) rescue RuntimeError => e raise unless e.message == 'Content Export for Outcomes Service failed' Canvas::Errors.capture(e) # mark migration failed, optionally begin a new export end
Prevention
- Check remote export state/logs via service UI when this raise fires
- Treat as terminal — re-queue a fresh export rather than re-polling
- Alert on 'failed' export states from the outcomes service
When it happens
Trigger: Polling an export whose remote content export transitioned to state 'failed' on the outcomes service side.
Common situations: Remote export crashed (bad course data, internal error); export id from a previously failed run being re-polled.
Related errors
- Error retrieving export for Outcomes Service: #
- Error queueing export for Outcomes Service: #
- Error retrieving export state for Outcomes Service: #
- # : #
- Error parsing JSON results from Outcomes Service: #
AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15).
Data as JSON: /api/errors/d94ec53a825c32f6.
Report an issue: GitHub.
Appendix: source
Thrown at app/models/outcomes_service/migration_service.rb:67
{ export_id: json["id"], course: }
else
raise "Error queueing export for Outcomes Service: #{response.body}"
end
end
def export_completed?(export_data)
content_export_url = "#{OutcomesService::Service.url(export_data[:course])}/api/content_exports/#{export_data[:export_id]}"
response = CanvasHttp.get(
content_export_url,
headers_for(export_data[:course], "content_migration.export", id: export_data[:export_id])
)
if /^2/.match?(response.code.to_s)
json = JSON.parse(response.body)
case json["state"]
when "completed"
true
when "failed"
raise "Content Export for Outcomes Service failed"
else
false
end
else
raise "Error retrieving export state for Outcomes Service: #{response.body}"
end
end
def retrieve_export(export_data)
content_export_url = "#{OutcomesService::Service.url(export_data[:course])}/api/content_exports/#{export_data[:export_id]}"
response = CanvasHttp.get(
content_export_url,
headers_for(export_data[:course], "content_migration.export", id: export_data[:export_id])
)
if /^2/.match?(response.code.to_s)
json = JSON.parse(response.body)
json["data"]
elseView on GitHub (pinned to 1c9f0bb801)