{"record":{"id":"12e03e7298e99254","repo":"instructure/canvas-lms","slug":"not-importing-academic-benchmark-data-because-no-user-found","errorCode":null,"errorMessage":"Not importing academic benchmark data because no user found matching id '#{user_id}'","messagePattern":"Not importing academic benchmark data because no user found matching id '#(.+?)'","errorType":"exception","errorClass":"Canvas::Migration::Error","httpStatus":null,"severity":"error","filePath":"gems/plugins/academic_benchmark/lib/academic_benchmark.rb","lineNumber":221,"sourceCode":"  def self.authorized?\n    check_for_import_rights(\n      user: ensure_real_user(user_id: ensure_user_id_set)\n    )\n  end\n\n  def self.ensure_user_id_set\n    uid = Setting.get(\"academic_benchmark_migration_user_id\", nil)\n    unless uid.present?\n      raise Canvas::Migration::Error,\n            \"Not importing academic benchmark data because no user id set\"\n    end\n    uid\n  end\n\n  def self.ensure_real_user(user_id:)\n    u = User.find_by(id: user_id)\n    unless u\n      raise Canvas::Migration::Error,\n            \"Not importing academic benchmark data because no user found matching id '#{user_id}'\"\n    end\n    u\n  end\n\n  def self.check_for_import_rights(user:)\n    unless Account.site_admin.grants_right?(user, :manage_global_outcomes)\n      raise Canvas::Migration::Error,\n            \"Not importing academic benchmark data because user with ID \" \\\n            \"'#{user.id}' isn't allowed to edit global outcomes\"\n    end\n    user\n  end\nend\n","sourceCodeStart":203,"sourceCodeEnd":236,"githubUrl":"https://github.com/instructure/canvas-lms/blob/1c9f0bb8013ed69c4f2efe11fd483025469b7e6c/gems/plugins/academic_benchmark/lib/academic_benchmark.rb#L203-L236","documentation":"Canvas::Migration::Error raised by AcademicBenchmark.ensure_real_user when User.find_by(id: user_id) returns nil, i.e. no User record exists for the id passed into an academic benchmark standards import. The gem refuses to run the import because every outcome import must be attributed to a real user who can be permission-checked.","triggerScenarios":"Calling AcademicBenchmark.import/ensure_real_user with a user_id that is nil, deleted, from another shard, or otherwise not present in the users table.","commonSituations":"Queued migration jobs referencing a user removed before the job ran; cross-shard user ids not resolvable; tests passing a fabricated id; a content_migration whose user_id setting was never set.","solutions":["Verify the user_id passed to the import exists: User.find_by(id: user_id) in the rails console.","Fix the caller to resolve the actual importing user (e.g. from ContentMigration#user) instead of a stale id.","If the user was deleted, re-run the import with a valid site-admin user.","For cross-shard ids, ensure the id is a global id or that the lookup happens on the correct shard."],"exampleFix":"// before\nAcademicBenchmark.import(user_id: params[:user_id])\n// after\nuser = User.find_by(id: params[:user_id])\nraise ArgumentError, 'user not found' unless user\nAcademicBenchmark.import(user_id: user.id)","handlingStrategy":"validation","validationCode":"user = User.find_by(id: user_id)\nraise ArgumentError, \"user #{user_id} not found\" unless user\n# then call AcademicBenchmark.import(user_id: user.id)","typeGuard":"valid_user = ->(u) { u.is_a?(User) && u.persisted? }","tryCatchPattern":"begin\n  AcademicBenchmark.import(user_id: user_id)\nrescue Canvas::Migration::Error => e\n  Rails.logger.warn(\"benchmark import aborted: #{e.message}\")\nend","preventionTips":["Resolve the user from ContentMigration#user rather than caching ids in jobs.","Guard jobs against deleted users before enqueueing.","Use global ids for cross-shard lookups."],"tags":["record-not-found","migrations","ruby"],"backgroundTag":"record-not-found","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"}