instructure/canvas-lms · error · GraphQL::ExecutionError
Invalid section ids
Error message
Invalid section ids
What it means
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.
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
Example fix
// before
hideAssignmentGradesForSections(input: { assignmentId: "1", sectionIds: ["12", "99"] }) // 99 not in course
// after
const ids = course.sections.connection.filter(s => s.courseId === assignment.courseId).map(s => s.id);
hideAssignmentGradesForSections(input: { assignmentId: "1", sectionIds: ids }); Defensive patterns
Strategy: validation
Validate before calling
const ids = input.sectionIds;
const sections = (await course.sectionsConnection).filter(s => ids.includes(s.id));
if (sections.length !== ids.length || ids.length === 0) throw new Error("Invalid section ids"); Try / catch
try {
await hideAssignmentGradesForSections(input);
} catch (e) {
if (e.message.includes("Invalid section ids")) {
// refresh section ids from the course and retry once
}
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Auto-grading failed due to the following issue(s): #
- cannot import a root group
- Invalid context type
- Outcome is not available in context #
- Outcome is not available in context #
AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15).
Data as JSON: /api/errors/4ed8af5f5fb3ca50.
Report an issue: GitHub.
Appendix: source
Thrown at app/graphql/mutations/hide_assignment_grades_for_sections.rb:48
def resolve(input:)
begin
assignment = AbstractAssignment.find_assignment_or_peer_review(input[:assignment_id])
course = assignment.context
sections = course.course_sections.where(id: input[:section_ids])
rescue ActiveRecord::RecordNotFound
raise GraphQL::ExecutionError, "not found"
end
verify_authorized_action!(assignment, :grade)
unless assignment.grades_published?
raise GraphQL::ExecutionError, "Assignments under moderation cannot be hidden by section before grades are published"
end
raise GraphQL::ExecutionError, "Anonymous assignments cannot be hidden by section" if assignment.anonymize_students?
if sections.empty? || sections.count != input[:section_ids].size
raise GraphQL::ExecutionError, "Invalid section ids"
end
visible_enrollments = course.apply_enrollment_visibility(course.student_enrollments, current_user, sections)
submissions_scope = input[:graded_only] ? assignment.submissions.graded : assignment.submissions
submissions_scope = submissions_scope.joins(user: :enrollments).merge(visible_enrollments)
progress = course.progresses.new(tag: "hide_assignment_grades_for_sections")
if progress.save
progress.process_job(
assignment,
:hide_submissions,
{ preserve_method_args: true, priority: Delayed::HIGH_PRIORITY },
progress:,
submission_ids: submissions_scope.pluck(:id),
skip_content_participation_refresh: false
)View on GitHub (pinned to 1c9f0bb801)