instructure/canvas-lms · error
require course
Error message
require course
What it means
Courses::TimetableEventBuilder#initialize requires a course: the builder generates calendar events scoped to a course (optionally a section), so constructing it without a course raises 'require course' immediately.
Solutions
- Resolve the Course and pass course: course to the builder.
- Validate the course lookup succeeded before constructing the builder and surface a user-facing error if not.
- If operating on a section only, still pass its course: builder.new(course: section.course, course_section: section).
Example fix
// before builder = TimetableEventBuilder.new(course_section: section) // after raise 'course not found' unless course builder = TimetableEventBuilder.new(course: course, course_section: section)
Defensive patterns
Strategy: type-guard
Validate before calling
raise 'course not found' if course.nil? TimetableEventBuilder.new(course: course, course_section: section)
Type guard
def buildable?(course, section = nil) course.is_a?(Course) end
Prevention
- Fail early with a clear message when course lookup returns nil
- Never rely on course_section alone; always resolve its course
- Type-check constructor inputs in importer entry points
When it happens
Trigger: Courses::TimetableEventBuilder.new(course_section: section) with course omitted; passing course: nil from a caller whose lookup failed; passing only course_section even though the builder keys on course.
Common situations: Timetable importers where the Course lookup by sis_id/name returned nil and the nil was forwarded; misuse assuming course_section alone suffices; refactors that renamed a local variable used as the course: argument.
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
- timetable codes can't be blank
- Course pace is deleted
- Course pace is not deleted
- Course required
- invalid association
AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15).
Data as JSON: /api/errors/104cdf14c7bf2f9d.
Report an issue: GitHub.
Appendix: source
Thrown at app/models/courses/timetable_event_builder.rb:27
# the terms of the GNU Affero General Public License as published by the Free
# Software Foundation, version 3 of the License.
#
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
module Courses
class TimetableEventBuilder
# builds calendar events for a course (or course sections) according to a timetable
attr_reader :course, :course_section, :event_context, :errors
def initialize(course: nil, course_section: nil)
raise "require course" unless course
@course = course
@course_section = course_section
@event_context = course_section || course
end
# generates individual events from a simplified "timetable" between the course/section start and end dates
# :weekdays - days of week (0-Sunday, 1-Monday, 2-Tuesday, 3-Wednesday, 4-Thursday, 5-Friday, 6-Saturday)
# :start_time - basically any time that can be parsed by the magic (e.g. "11:30 am")
# :end_time - ditto
# :location_name (optional)
def generate_event_hashes(timetable_hashes)
time_zone = course.time_zone
event_hashes = []
timetable_hashes.each do |timetable_hash|
course_start_at = timetable_hash[:course_start_at]
course_end_at = timetable_hash[:course_end_at]
View on GitHub (pinned to 1c9f0bb801)