{"record":{"id":"4ed8af5f5fb3ca50","repo":"instructure/canvas-lms","slug":"invalid-section-ids","errorCode":null,"errorMessage":"Invalid section ids","messagePattern":"Invalid section ids","errorType":"exception","errorClass":"GraphQL::ExecutionError","httpStatus":null,"severity":"error","filePath":"app/graphql/mutations/hide_assignment_grades_for_sections.rb","lineNumber":48,"sourceCode":"\n  def resolve(input:)\n    begin\n      assignment = AbstractAssignment.find_assignment_or_peer_review(input[:assignment_id])\n      course = assignment.context\n      sections = course.course_sections.where(id: input[:section_ids])\n    rescue ActiveRecord::RecordNotFound\n      raise GraphQL::ExecutionError, \"not found\"\n    end\n\n    verify_authorized_action!(assignment, :grade)\n\n    unless assignment.grades_published?\n      raise GraphQL::ExecutionError, \"Assignments under moderation cannot be hidden by section before grades are published\"\n    end\n    raise GraphQL::ExecutionError, \"Anonymous assignments cannot be hidden by section\" if assignment.anonymize_students?\n\n    if sections.empty? || sections.count != input[:section_ids].size\n      raise GraphQL::ExecutionError, \"Invalid section ids\"\n    end\n\n    visible_enrollments = course.apply_enrollment_visibility(course.student_enrollments, current_user, sections)\n\n    submissions_scope = input[:graded_only] ? assignment.submissions.graded : assignment.submissions\n    submissions_scope = submissions_scope.joins(user: :enrollments).merge(visible_enrollments)\n\n    progress = course.progresses.new(tag: \"hide_assignment_grades_for_sections\")\n\n    if progress.save\n      progress.process_job(\n        assignment,\n        :hide_submissions,\n        { preserve_method_args: true, priority: Delayed::HIGH_PRIORITY },\n        progress:,\n        submission_ids: submissions_scope.pluck(:id),\n        skip_content_participation_refresh: false\n      )","sourceCodeStart":30,"sourceCodeEnd":66,"githubUrl":"https://github.com/instructure/canvas-lms/blob/1c9f0bb8013ed69c4f2efe11fd483025469b7e6c/app/graphql/mutations/hide_assignment_grades_for_sections.rb#L30-L66","documentation":"HideAssignmentGradesForSections mutation rejects the request when the set of CourseSection records resolved from section_ids does not exactly match the section_ids the caller sent. Either no sections matched (empty) or some ids did not resolve to sections of the assignment's course. It is a caller-input validation guard before the hide-submissions job is queued.","triggerScenarios":"Calling mutation hideAssignmentGradesForSections with section_ids containing: ids that belong to a different course, already-deleted sections, malformed/garbage ids, duplicates combined with an unresolvable id (count mismatch), or a mix of relay and legacy ids that do not all resolve.","commonSituations":"Cross-course copy-paste of section ids; using sections from a course after section merges/deletions; passing section ids from a staging database into a production request; hardcoding section ids that changed between environments; sending both relay global ids and numeric legacy ids mixed.","solutions":["Query the course's course_sections (active only) and send only ids that belong to assignment.context_id","Re-fetch section ids via GraphQL (course.sections connection) instead of caching them","Ensure ids are the accepted format (relay global ids via the mutation's prepare helper or plain legacy numeric ids)","Check for duplicate ids in the payload; duplicates plus any unresolvable id cause a count mismatch"],"exampleFix":"// before\nhideAssignmentGradesForSections(input: { assignmentId: \"1\", sectionIds: [\"12\", \"99\"] }) // 99 not in course\n// after\nconst ids = course.sections.connection.filter(s => s.courseId === assignment.courseId).map(s => s.id);\nhideAssignmentGradesForSections(input: { assignmentId: \"1\", sectionIds: ids });","handlingStrategy":"validation","validationCode":"const ids = input.sectionIds;\nconst sections = (await course.sectionsConnection).filter(s => ids.includes(s.id));\nif (sections.length !== ids.length || ids.length === 0) throw new Error(\"Invalid section ids\");","typeGuard":null,"tryCatchPattern":"try {\n  await hideAssignmentGradesForSections(input);\n} catch (e) {\n  if (e.message.includes(\"Invalid section ids\")) {\n    // refresh section ids from the course and retry once\n  }\n}","preventionTips":["Always resolve section ids from the assignment's own course via GraphQL immediately before the call","Deduplicate sectionIds before sending","Never hardcode section ids across environments","Account for deleted/merged sections by re-querying active sections"],"tags":["graphql","validation","invalid-argument","canvas-lms"],"backgroundTag":"invalid-argument-value","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"}