{"record":{"id":"5d9f22c160b00721","repo":"instructure/canvas-lms","slug":"must-provide-at-least-course-id","errorCode":null,"errorMessage":"Must provide at least course_id","messagePattern":"Must provide at least course_id","errorType":"exception","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"app/helpers/canvas_outcomes_helper.rb","lineNumber":241,"sourceCode":"    # test_cluster? and test_cluster_name are true and not nil for nonprod environments,\n    # like beta or test\n    if ApplicationController.test_cluster?\n      :\"#{ApplicationController.test_cluster_name}_domain\"\n    else\n      :domain\n    end\n  end\n\n  def build_request_url(protocol, domain, endpoint, params)\n    url = \"#{protocol}://#{domain}/#{endpoint}\"\n    if params.present?\n      url += \"?\" + params.to_query\n    end\n    url\n  end\n\n  def enqueue_rollup_calculation(course_id: nil, student_id: nil, outcome_id: nil)\n    raise ArgumentError, \"Must provide at least course_id\" unless course_id\n    return unless Account.site_admin.feature_enabled?(:outcomes_rollup_propagation)\n\n    if course_id && student_id\n      Outcomes::StudentOutcomeRollupCalculationService.calculate_for_student(\n        course_id:,\n        student_id:\n      )\n    else\n      Outcomes::StudentOutcomeRollupCalculationService.calculate_for_course(\n        course_id:\n      )\n    end\n  end\n\n  private\n\n  def artifact_type_lookup(artifact)\n    case artifact.class.to_s","sourceCodeStart":223,"sourceCodeEnd":259,"githubUrl":"https://github.com/instructure/canvas-lms/blob/1c9f0bb8013ed69c4f2efe11fd483025469b7e6c/app/helpers/canvas_outcomes_helper.rb#L223-L259","documentation":"enqueue_rollup_calculation in CanvasOutcomesHelper enqueues outcome rollup calculation jobs and requires a course_id to scope the work. It raises ArgumentError immediately when course_id is nil, before checking the outcomes_rollup_propagation feature flag.","triggerScenarios":"Calling enqueue_rollup_calculation without course_id (or with course_id: nil), e.g. from a controller where the course param was absent, or from a job/callback that conditionally sets the course.","commonSituations":"A request missing the course context; refactoring changed the keyword argument name so the old value no longer binds; a batch job iterating items where some lack an associated course.","solutions":["Always pass course_id: when calling enqueue_rollup_calculation","Guard the call site: skip enqueueing when course_id is nil instead of relying on the raise","Trace back why the course was missing (missing param, bad association) and fix at the source","Ensure the caller has the course loaded from params[:course_id] before invoking"],"exampleFix":"// before\nenqueue_rollup_calculation(student_id: student.id, outcome_id: outcome.id)\n// after\nenqueue_rollup_calculation(course_id: course.id, student_id: student.id, outcome_id: outcome.id)","handlingStrategy":"validation","validationCode":"raise ArgumentError, 'Must provide at least course_id' unless course_id\nenqueue_rollup_calculation(course_id: course_id, ...)","typeGuard":null,"tryCatchPattern":"begin\n  enqueue_rollup_calculation(course_id: course.id)\nrescue ArgumentError => e\n  Rails.logger.warn(\"skipped rollup enqueue: #{e.message}\")\nend","preventionTips":["Require course context in the controller before the helper call","Guard call sites: return early when course is nil","Keyword-arg name changes: search all callers when renaming"],"tags":["ruby","arguments","outcomes-rollup"],"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"}