instructure/canvas-lms · error · ActiveRecord::RecordNotFound

polling.poll_sessions.errors.course_required

polling.poll_sessions.errors.course_required

Error message

Course is required.

What it means

When creating a poll session via the polling API, the course_id is deleted from params and used to find @course; if no course_id was supplied (or set otherwise) @course is nil and Canvas raises ActiveRecord::RecordNotFound 'Course is required.' (code polling.poll_sessions.errors.course_required), rendered per API error conventions.

Solutions

  1. Include course_id in the poll_session params of the POST body (JSON: { "poll_session": { "course_id": 1, ... } })
  2. Verify the nesting/key name matches the API docs (poll_session[poll_id], course_id)
  3. Confirm the course id is numeric and the course exists and is accessible to the caller
  4. If your serializer omits empty fields, ensure course_id is explicitly set

Example fix

// before
POST /api/v1/polls/5/poll_sessions {"poll_session":{"course_section_id":9}}
// after
POST /api/v1/polls/5/poll_sessions {"poll_session":{"course_id":42,"course_section_id":9}}
Defensive patterns

Strategy: validation

Validate before calling

function buildPollSessionPayload({ courseId, courseSectionId, ...rest }) {
  if (!Number.isInteger(courseId)) throw new TypeError('poll_session requires a numeric course_id');
  return { poll_session: { course_id: courseId, course_section_id: courseSectionId, ...rest } };
}

Try / catch

try { await createPollSession(payload); } catch (e) { if (/Course is required/.test(e.response?.data?.message || '')) { throw new Error('POST body must include poll_session.course_id'); } throw e; }

Prevention

When it happens

Trigger: POST /api/v1/polls/:poll_id/poll_sessions with a JSON body lacking courses[].course_id (or course_id at the expected nesting), so get_poll_session_params yields no course_id.

Common situations: Sending poll_section_id but forgetting course_id, wrong param nesting in the JSON:poll_session wrapper, or the client dropping nil fields during serialization.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15). Data as JSON: /api/errors/1e6e9c8ab22db3c1. Report an issue: GitHub.

Appendix: source

Thrown at app/controllers/polling/poll_sessions_controller.rb:142

    # @argument poll_sessions[][course_section_id] [Integer]
    #   The id of the course section this session is associated with.
    #
    # @argument poll_sessions[][has_public_results] [Boolean]
    #   Whether or not results are viewable by students.
    #
    # @example_response
    #   {
    #     "poll_sessions": [PollSession]
    #   }
    #
    def create
      poll_session_params = get_poll_session_params

      if (course_id = poll_session_params.delete(:course_id))
        @course = Course.find(course_id)
      end

      raise ActiveRecord::RecordNotFound, I18n.t("polling.poll_sessions.errors.course_required", "Course is required.") unless @course

      if (course_section_id = poll_session_params.delete(:course_section_id))
        @course_section = @course.course_sections.find(course_section_id)
      end

      @poll_session = @course.poll_sessions.build(poll_session_params.merge(poll: @poll,
                                                                            course_section: @course_section))

      @poll_session.has_public_results = false if poll_session_params[:has_public_results].blank?

      if authorized_action(@poll, @current_user, :create) && authorized_action(@course, @current_user, :update)
        if @poll_session.save
          render json: serialize_jsonapi(@poll_session)
        else
          render json: @poll_session.errors, status: :bad_request
        end
      end
    end

View on GitHub (pinned to 1c9f0bb801)