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

unknown context type

Error message

unknown context type

What it means

The SIS API context resolver memoizes @context from either account_id or course_id params. If neither is present, it raises ActiveRecord::RecordNotFound with 'unknown context type' to signal the request lacks a resolvable context.

Solutions

  1. Include account_id (e.g. ?account_id=1) or course_id in the request params.
  2. Convert sis ids to numeric canvas ids before calling (sis_course_id:... is not accepted here).
  3. Check the endpoint documentation for which context param it requires.

Example fix

// before
GET /api/sis/accounts/1/published_courses
// after
GET /api/sis/accounts/1/published_courses?account_id=1
Defensive patterns

Strategy: validation

Validate before calling

if (!params.account_id && !params.course_id) throw new Error('SIS API call requires account_id or course_id')

Try / catch

try { const res = await fetch(url) } catch (e) { /* handle 404 with message 'unknown context type' by adding account_id/course_id and retrying */ }

Prevention

When it happens

Trigger: GET/POST to any SIS API endpoint (e.g. /api/sis/...) without an account_id or course_id query/body param.

Common situations: API clients omitting required context params; tools hitting versioned endpoints where the param name changed; scripts hitting a course-scoped endpoint with only sis_course_id instead of course_id.

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/e3f83bab01ed941e. Report an issue: GitHub.

Appendix: source

Thrown at app/controllers/sis_api_controller.rb:370

  # information to include.
  #
  #   "student_overrides":: returns individual student override information
  #
  def sis_assignments
    includes = { student_overrides: include_student_overrides? }
    render json: sis_assignments_json(paginated_assignments, includes:, current_user: @current_user)
  end

  private

  def context
    @context ||=
      if params[:account_id]
        api_find(Account, params[:account_id])
      elsif params[:course_id]
        api_find(Course, params[:course_id])
      else
        raise ActiveRecord::RecordNotFound, "unknown context type"
      end
  end

  def published_course_ids
    case context
    when Account
      course_scope = Course.published.where(account_id: [context.id] + Account.sub_account_ids_recursive(context.id))
      if (starts_before = CanvasTime.try_parse(params[:starts_before]))
        course_scope = course_scope.where("
        (courses.start_at IS NULL AND enrollment_terms.start_at IS NULL)
        OR courses.start_at < ? OR enrollment_terms.start_at < ?",
                                          starts_before,
                                          starts_before)
      end
      if (ends_after = CanvasTime.try_parse(params[:ends_after]))
        course_scope = course_scope.where("
        (courses.conclude_at IS NULL AND enrollment_terms.end_at IS NULL)
        OR courses.conclude_at > ? OR enrollment_terms.end_at > ?",

View on GitHub (pinned to 1c9f0bb801)