{"record":{"id":"e3f83bab01ed941e","repo":"instructure/canvas-lms","slug":"unknown-context-type-sis-api-controller","errorCode":null,"errorMessage":"unknown context type","messagePattern":"unknown context type","errorType":"exception","errorClass":"ActiveRecord::RecordNotFound","httpStatus":404,"severity":"error","filePath":"app/controllers/sis_api_controller.rb","lineNumber":370,"sourceCode":"  # information to include.\n  #\n  #   \"student_overrides\":: returns individual student override information\n  #\n  def sis_assignments\n    includes = { student_overrides: include_student_overrides? }\n    render json: sis_assignments_json(paginated_assignments, includes:, current_user: @current_user)\n  end\n\n  private\n\n  def context\n    @context ||=\n      if params[:account_id]\n        api_find(Account, params[:account_id])\n      elsif params[:course_id]\n        api_find(Course, params[:course_id])\n      else\n        raise ActiveRecord::RecordNotFound, \"unknown context type\"\n      end\n  end\n\n  def published_course_ids\n    case context\n    when Account\n      course_scope = Course.published.where(account_id: [context.id] + Account.sub_account_ids_recursive(context.id))\n      if (starts_before = CanvasTime.try_parse(params[:starts_before]))\n        course_scope = course_scope.where(\"\n        (courses.start_at IS NULL AND enrollment_terms.start_at IS NULL)\n        OR courses.start_at < ? OR enrollment_terms.start_at < ?\",\n                                          starts_before,\n                                          starts_before)\n      end\n      if (ends_after = CanvasTime.try_parse(params[:ends_after]))\n        course_scope = course_scope.where(\"\n        (courses.conclude_at IS NULL AND enrollment_terms.end_at IS NULL)\n        OR courses.conclude_at > ? OR enrollment_terms.end_at > ?\",","sourceCodeStart":352,"sourceCodeEnd":388,"githubUrl":"https://github.com/instructure/canvas-lms/blob/1c9f0bb8013ed69c4f2efe11fd483025469b7e6c/app/controllers/sis_api_controller.rb#L352-L388","documentation":"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.","triggerScenarios":"GET/POST to any SIS API endpoint (e.g. /api/sis/...) without an account_id or course_id query/body param.","commonSituations":"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.","solutions":["Include account_id (e.g. ?account_id=1) or course_id in the request params.","Convert sis ids to numeric canvas ids before calling (sis_course_id:... is not accepted here).","Check the endpoint documentation for which context param it requires."],"exampleFix":"// before\nGET /api/sis/accounts/1/published_courses\n// after\nGET /api/sis/accounts/1/published_courses?account_id=1","handlingStrategy":"validation","validationCode":"if (!params.account_id && !params.course_id) throw new Error('SIS API call requires account_id or course_id')","typeGuard":null,"tryCatchPattern":"try { const res = await fetch(url) } catch (e) { /* handle 404 with message 'unknown context type' by adding account_id/course_id and retrying */ }","preventionTips":["Always build SIS API URLs from a resolved canvas account or course id","Convert sis ids to numeric ids first","Keep param names in sync with the endpoint version"],"tags":["api","params","record-not-found"],"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"}