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

  1. Check the outcomes service logs for the export id to find the remote failure cause
  2. Queue a new export via begin_export and retry the migration
  3. 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

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


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"]
        else

View on GitHub (pinned to 1c9f0bb801)