instructure/canvas-lms · critical · RuntimeError

Error queueing export for Outcomes Service: #

Error message

Error queueing export for Outcomes Service: #{response.body}

What it means

OutcomesService::MigrationService.begin_export POSTs to the outcomes service to queue a content export; if the HTTP response code is not 2xx it raises including the raw response body, signaling the export could not be queued.

Solutions

  1. Inspect the response body in the message for the specific HTTP error and fix accordingly
  2. Verify OutcomesService::Service.url configuration and service health
  3. Check JWT/token generation in headers_for and service auth
  4. Retry after the service recovers
Defensive patterns

Strategy: retry

Validate before calling

raise 'outcomes service URL not configured' unless OutcomesService::Service.url
# verify service reachable before export
CanvasHttp.get(OutcomesService::Service.url + '/health') if respond_to?(:health_check)

Try / catch

begin
  MigrationService.begin_export(course, opts)
rescue RuntimeError => e
  raise unless e.message.start_with?('Error queueing export')
  Canvas::Errors.capture(e)
  retry_after_delay { MigrationService.begin_export(course, opts) }
end

Prevention

When it happens

Trigger: The outcomes service returns a non-2xx status to the queue-export request (auth failure from expired JWT, service down, bad course/export payload, 404 because the course is not known to the outcomes service).

Common situations: Misconfigured OutcomesService URL; live-events/outcomes-service integration outage; token/JWT clock skew; course not registered in outcomes service.

Understand the failure class

Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.

Related errors


AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15). Data as JSON: /api/errors/5ad6aa13d7551383. Report an issue: GitHub.

Appendix: source

Thrown at app/models/outcomes_service/migration_service.rb:51

          context_type: "course",
          context_id: course.id.to_s,
          export_settings: {
            format: "canvas",
            artifacts:
          }
        }
        content_exports_url = "#{OutcomesService::Service.url(course)}/api/content_exports"
        response = CanvasHttp.post(
          content_exports_url,
          headers_for(course, "content_migration.export", context_type: "course", context_id: course.id.to_s),
          body: data.to_json,
          content_type: "application/json"
        )
        if /^2/.match?(response.code.to_s)
          json = JSON.parse(response.body)
          { 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

View on GitHub (pinned to 1c9f0bb801)