{"record":{"id":"0b15ec6f2cf7cc17","repo":"instructure/canvas-lms","slug":"missing-required-content-migration-settings","errorCode":null,"errorMessage":"Missing required content_migration settings","messagePattern":"Missing required content_migration settings","errorType":"exception","errorClass":"Canvas::Migration::Error","httpStatus":null,"severity":"error","filePath":"gems/plugins/academic_benchmark/lib/academic_benchmark/converter.rb","lineNumber":34,"sourceCode":"#\n# You should have received a copy of the GNU Affero General Public License along\n# with this program. If not, see <http://www.gnu.org/licenses/>.\n\nrequire \"academic_benchmarks\"\n\nmodule AcademicBenchmark\n  class Converter < Canvas::Migration::Migrator\n    def initialize(settings = {})\n      super(settings, \"academic_benchmark\")\n      @ratings_overrides = settings[:migration_options] || {}\n      @course[:learning_outcomes] = []\n      @partner_id = settings[:partner_id]\n      @partner_key = settings[:partner_key]\n    end\n\n    def export\n      unless content_migration\n        raise Canvas::Migration::Error,\n              \"Missing required content_migration settings\"\n      end\n      unless Account.site_admin.grants_right?(content_migration.user, :manage_global_outcomes)\n        raise Canvas::Migration::Error,\n              \"User isn't allowed to edit global outcomes\"\n      end\n      unless @archive_file\n        unless @partner_id.present? || AcademicBenchmark.ensure_partner_id.nil?\n          raise Canvas::Migration::Error, I18n.t(\"A partner ID is required to use Academic Benchmarks\")\n        end\n        unless @partner_key.present? || AcademicBenchmark.ensure_partner_key.nil?\n          raise Canvas::Migration::Error, I18n.t(\"A partner key is required to use Academic Benchmarks\")\n        end\n      end\n      if outcome_data.present?\n        if outcome_data.instance_of? AcademicBenchmarks::Standards::StandardsForest\n          outcome_data.trees.each do |t|\n            @course[:learning_outcomes] << t.root.build_outcomes(@ratings_overrides)","sourceCodeStart":16,"sourceCodeEnd":52,"githubUrl":"https://github.com/instructure/canvas-lms/blob/1c9f0bb8013ed69c4f2efe11fd483025469b7e6c/gems/plugins/academic_benchmark/lib/academic_benchmark/converter.rb#L16-L52","documentation":"Canvas::Migration::Error raised at the start of AcademicBenchmark::Converter#export when @content_migration is nil. The converter requires a content_migration object both to attribute the import to a user and to store results; without it export cannot proceed.","triggerScenarios":"Instantiating AcademicBenchmark::Converter with settings lacking a content_migration (the settings hash must include content_migration or be constructed via with_content_migration) and then calling export.","commonSituations":"Custom scripts or jobs constructing the converter directly without wiring a ContentMigration; refactors dropping the content_migration setting; test harnesses building a bare settings hash.","solutions":["Pass a persisted ContentMigration into the converter settings: { content_migration: cm, ... }.","Use the standard migration pipeline (ContentMigration job) so content_migration is set automatically.","In tests, stub or build a ContentMigration record instead of omitting the key.","Guard before export: raise early if settings[:content_migration].nil?."],"exampleFix":"// before\nconverter = AcademicBenchmark::Converter.new(partner_id: pid, partner_key: key)\nconverter.export\n// after\ncm = ContentMigration.create!(context: Account.site_admin, user: admin)\nconverter = AcademicBenchmark::Converter.new({ content_migration: cm, partner_id: pid, partner_key: key })\nconverter.export","handlingStrategy":"validation","validationCode":"raise ArgumentError, 'content_migration required' unless settings[:content_migration]","typeGuard":null,"tryCatchPattern":"begin\n  converter.export\nrescue Canvas::Migration::Error => e\n  Rails.logger.error(\"academic benchmark export failed: #{e.message}\")\n  cm.fail!\nend","preventionTips":["Always build the converter through the standard migration pipeline.","Assert content_migration presence in converter specs/setup.","Don't construct converters ad hoc in scripts without a ContentMigration."],"tags":["missing-argument","migrations","ruby"],"backgroundTag":"missing-required-argument","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"}