instructure/canvas-lms · error · QueryError
Searching for announcements in sections must span exactly…
Error message
Searching for announcements in sections must span exactly one course
What it means
DiscussionTopic.in_sections is a scope that builds an announcements query for a given array of CourseSection objects. It requires that all provided sections belong to exactly one course; otherwise the query would span multiple courses. When the unique course_id set has a size other than 1 (including zero sections), it raises QueryError.
Solutions
- Group sections by course_id and call in_sections once per course, merging results.
- Verify before calling: raise or short-circuit if sections.map(&:course_id).uniq.size != 1.
- Handle empty input separately instead of passing it to in_sections.
Example fix
// before Announcement.in_sections(sections) // after sections.group_by(&:course_id).each do |_, secs| Announcement.in_sections(secs) end
Defensive patterns
Strategy: validation
Validate before calling
course_ids = sections.map(&:course_id).uniq raise "sections must span exactly one course" unless course_ids.size == 1
Try / catch
begin
Announcement.in_sections(sections)
rescue QueryError => e
Rails.logger.warn("in_sections rejected: #{e.message}")
sections.group_by(&:course_id).flat_map { |_, s| Announcement.in_sections(s) }
end Prevention
- Always derive sections from a single course context
- Check sections.map(&:course_id).uniq.size == 1 before calling
- Handle empty section lists separately
When it happens
Trigger: Calling DiscussionTopic.in_sections(sections) with sections from two or more different courses, or with an empty/unmatched relation that yields no course_ids.
Common situations: Account-level dashboards aggregating section-scoped announcements across multiple courses; passing a relation filtered by a deleted course (empty set).
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
- Cannot call with more than one user
- A course did not pass validation
- A # user did not pass validation (user: # , # : # , error…
- A # did not pass validation (# : # , error: # )
- A # did not pass validation (# : # , error: # )
AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15).
Data as JSON: /api/errors/023dad92518e7a38.
Report an issue: GitHub.
Appendix: source
Thrown at app/models/discussion_topic.rb:906
class QueryError < StandardError
attr_accessor :status_code
def initialize(message = nil, status_code = nil)
super(message)
self.status_code = status_code
end
end
# Retrieves all the *course* (as oppposed to group) discussion topics that apply
# to the given sections. Group topics will not be returned. TODO: figure out
# a good way to deal with group topics here.
#
# Takes in an array of section objects, and it is required that they all belong
# to the same course. At least one section must be provided.
scope :in_sections, lambda { |course_sections|
course_ids = course_sections.pluck(:course_id).uniq
if course_ids.length != 1
raise QueryError, I18n.t("Searching for announcements in sections must span exactly one course")
end
course_id = course_ids.first
joins("LEFT OUTER JOIN #{DiscussionTopicSectionVisibility.quoted_table_name}
AS discussion_section_visibilities ON discussion_topics.is_section_specific = true AND
discussion_section_visibilities.discussion_topic_id = discussion_topics.id")
.where("discussion_topics.context_type = 'Course' AND
discussion_topics.context_id = :course_id",
{ course_id: })
.where("discussion_section_visibilities.id IS null OR
(discussion_section_visibilities.workflow_state = 'active' AND
discussion_section_visibilities.course_section_id IN (:course_sections))",
{ course_sections: course_sections.pluck(:id) }).distinct
}
scope :discussion_topic_section_visibility_scope, lambda { |student|
DiscussionTopicSectionVisibility
.select(1)View on GitHub (pinned to 1c9f0bb801)