{"record":{"id":"1e6e9c8ab22db3c1","repo":"instructure/canvas-lms","slug":"polling-poll-sessions-errors-course-required","errorCode":"polling.poll_sessions.errors.course_required","errorMessage":"Course is required.","messagePattern":"Course is required\\.","errorType":"exception","errorClass":"ActiveRecord::RecordNotFound","httpStatus":404,"severity":"error","filePath":"app/controllers/polling/poll_sessions_controller.rb","lineNumber":142,"sourceCode":"    # @argument poll_sessions[][course_section_id] [Integer]\n    #   The id of the course section this session is associated with.\n    #\n    # @argument poll_sessions[][has_public_results] [Boolean]\n    #   Whether or not results are viewable by students.\n    #\n    # @example_response\n    #   {\n    #     \"poll_sessions\": [PollSession]\n    #   }\n    #\n    def create\n      poll_session_params = get_poll_session_params\n\n      if (course_id = poll_session_params.delete(:course_id))\n        @course = Course.find(course_id)\n      end\n\n      raise ActiveRecord::RecordNotFound, I18n.t(\"polling.poll_sessions.errors.course_required\", \"Course is required.\") unless @course\n\n      if (course_section_id = poll_session_params.delete(:course_section_id))\n        @course_section = @course.course_sections.find(course_section_id)\n      end\n\n      @poll_session = @course.poll_sessions.build(poll_session_params.merge(poll: @poll,\n                                                                            course_section: @course_section))\n\n      @poll_session.has_public_results = false if poll_session_params[:has_public_results].blank?\n\n      if authorized_action(@poll, @current_user, :create) && authorized_action(@course, @current_user, :update)\n        if @poll_session.save\n          render json: serialize_jsonapi(@poll_session)\n        else\n          render json: @poll_session.errors, status: :bad_request\n        end\n      end\n    end","sourceCodeStart":124,"sourceCodeEnd":160,"githubUrl":"https://github.com/instructure/canvas-lms/blob/1c9f0bb8013ed69c4f2efe11fd483025469b7e6c/app/controllers/polling/poll_sessions_controller.rb#L124-L160","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Include course_id in the poll_session params of the POST body (JSON: { \"poll_session\": { \"course_id\": 1, ... } })","Verify the nesting/key name matches the API docs (poll_session[poll_id], course_id)","Confirm the course id is numeric and the course exists and is accessible to the caller","If your serializer omits empty fields, ensure course_id is explicitly set"],"exampleFix":"// before\nPOST /api/v1/polls/5/poll_sessions {\"poll_session\":{\"course_section_id\":9}}\n// after\nPOST /api/v1/polls/5/poll_sessions {\"poll_session\":{\"course_id\":42,\"course_section_id\":9}}","handlingStrategy":"validation","validationCode":"function buildPollSessionPayload({ courseId, courseSectionId, ...rest }) {\n  if (!Number.isInteger(courseId)) throw new TypeError('poll_session requires a numeric course_id');\n  return { poll_session: { course_id: courseId, course_section_id: courseSectionId, ...rest } };\n}","typeGuard":null,"tryCatchPattern":"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; }","preventionTips":["Always include course_id when creating poll sessions; section alone is not enough","Match the documented JSON nesting (poll_session wrapper) exactly","Beware serializers that drop nil/undefined fields","Validate ids are numeric before sending"],"tags":["polling","validation","missing-parameter","canvas-lms"],"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"}