{"record":{"id":"5ad6aa13d7551383","repo":"instructure/canvas-lms","slug":"error-queueing-export-for-outcomes-service-response-body","errorCode":null,"errorMessage":"Error queueing export for Outcomes Service: #{response.body}","messagePattern":"Error queueing export for Outcomes Service: #(.+?)","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"critical","filePath":"app/models/outcomes_service/migration_service.rb","lineNumber":51,"sourceCode":"          context_type: \"course\",\n          context_id: course.id.to_s,\n          export_settings: {\n            format: \"canvas\",\n            artifacts:\n          }\n        }\n        content_exports_url = \"#{OutcomesService::Service.url(course)}/api/content_exports\"\n        response = CanvasHttp.post(\n          content_exports_url,\n          headers_for(course, \"content_migration.export\", context_type: \"course\", context_id: course.id.to_s),\n          body: data.to_json,\n          content_type: \"application/json\"\n        )\n        if /^2/.match?(response.code.to_s)\n          json = JSON.parse(response.body)\n          { export_id: json[\"id\"], course: }\n        else\n          raise \"Error queueing export for Outcomes Service: #{response.body}\"\n        end\n      end\n\n      def export_completed?(export_data)\n        content_export_url = \"#{OutcomesService::Service.url(export_data[:course])}/api/content_exports/#{export_data[:export_id]}\"\n        response = CanvasHttp.get(\n          content_export_url,\n          headers_for(export_data[:course], \"content_migration.export\", id: export_data[:export_id])\n        )\n        if /^2/.match?(response.code.to_s)\n          json = JSON.parse(response.body)\n          case json[\"state\"]\n          when \"completed\"\n            true\n          when \"failed\"\n            raise \"Content Export for Outcomes Service failed\"\n          else\n            false","sourceCodeStart":33,"sourceCodeEnd":69,"githubUrl":"https://github.com/instructure/canvas-lms/blob/1c9f0bb8013ed69c4f2efe11fd483025469b7e6c/app/models/outcomes_service/migration_service.rb#L33-L69","documentation":"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.","triggerScenarios":"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).","commonSituations":"Misconfigured OutcomesService URL; live-events/outcomes-service integration outage; token/JWT clock skew; course not registered in outcomes service.","solutions":["Inspect the response body in the message for the specific HTTP error and fix accordingly","Verify OutcomesService::Service.url configuration and service health","Check JWT/token generation in headers_for and service auth","Retry after the service recovers"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"raise 'outcomes service URL not configured' unless OutcomesService::Service.url\n# verify service reachable before export\nCanvasHttp.get(OutcomesService::Service.url + '/health') if respond_to?(:health_check)","typeGuard":null,"tryCatchPattern":"begin\n  MigrationService.begin_export(course, opts)\nrescue RuntimeError => e\n  raise unless e.message.start_with?('Error queueing export')\n  Canvas::Errors.capture(e)\n  retry_after_delay { MigrationService.begin_export(course, opts) }\nend","preventionTips":["Monitor outcomes service uptime and auth token expiry","Log full response body on failure for diagnosis","Add bounded retries around begin_export"],"tags":["ruby","http","outcomes-service","integration"],"backgroundTag":"http-error-response","analyzedSha":"1c9f0bb8013ed69c4f2efe11fd483025469b7e6c","analyzedAt":"2026-09-15T20:33:18.891Z","contentChangedAt":"2026-09-15T20:33:18.891Z","schemaVersion":2},"datasetVersion":"2026-09-23T02:17:17.105Z"}