{"record":{"id":"b3effd8ca31e6793","repo":"instructure/canvas-lms","slug":"a-partner-key-is-required-to-use-academic-benchmarks","errorCode":null,"errorMessage":"A partner key is required to use Academic Benchmarks","messagePattern":"A partner key is required to use Academic Benchmarks","errorType":"exception","errorClass":"Canvas::Migration::Error","httpStatus":null,"severity":"error","filePath":"gems/plugins/academic_benchmark/lib/academic_benchmark/converter.rb","lineNumber":46,"sourceCode":"      @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)\n          end\n        else\n          @course[:learning_outcomes] << outcome_data.root.build_outcomes(@ratings_overrides)\n        end\n      end\n      save_to_file\n      @course\n    end\n\n    def post_process; end\n\n    private","sourceCodeStart":28,"sourceCodeEnd":64,"githubUrl":"https://github.com/instructure/canvas-lms/blob/1c9f0bb8013ed69c4f2efe11fd483025469b7e6c/gems/plugins/academic_benchmark/lib/academic_benchmark/converter.rb#L28-L64","documentation":"Canvas::Migration::Error raised in Converter#export when no archive file is supplied and neither a settings partner_key nor the plugin-configured partner key (AcademicBenchmark.ensure_partner_key) is present. The partner key is the API secret paired with the partner ID.","triggerScenarios":"API-based standards export (no archive_file) where partner_id resolves (or its check passed) but @partner_key is blank and AcademicBenchmark.config[:partner_key] is nil.","commonSituations":"Partner ID configured but key field left blank; key stored only in ENV on a host where the env var is unset; settings hash passing partner_id but not partner_key.","solutions":["Set partner_key in the academic_benchmark plugin settings or pass it in the converter settings.","Verify both partner_id and partner_key are configured together.","Supply an archive_file to skip the API path entirely.","Confirm the environment variable feeding the key is present on the job-running host."],"exampleFix":"// before\nsettings = { content_migration: cm, partner_id: pid }\nconverter = AcademicBenchmark::Converter.new(settings)\n// after\nsettings = { content_migration: cm, partner_id: pid, partner_key: ENV['AB_PARTNER_KEY'] }\nconverter = AcademicBenchmark::Converter.new(settings)","handlingStrategy":"validation","validationCode":"cfg = AcademicBenchmark.config || {}\nunless settings[:archive_file] || settings[:partner_key].present? || cfg[:partner_key].present?\n  raise 'configure partner_key or provide an archive file'\nend","typeGuard":null,"tryCatchPattern":"begin\n  converter.export\nrescue Canvas::Migration::Error => e\n  Rails.logger.error(\"AB key missing: #{e.message}\")\nend","preventionTips":["Configure partner_id and partner_key together as one step.","Verify ENV-fed secrets exist on job-running hosts.","Smoke-test API access in CI before production imports."],"tags":["configuration","api","credentials"],"backgroundTag":"missing-credentials","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"}