instructure/canvas-lms · warning · ScanLimitExceededError
Course exceeds accessibility scan limit
Error message
Course exceeds accessibility scan limit
What it means
Accessibility::CourseScanService.queue_course_scan refuses to enqueue a new accessibility scan when course.exceeds_accessibility_scan_limit? is true, raising ScanLimitExceededError 'Course exceeds accessibility scan limit'. Very large courses are blocked from scanning to protect job throughput and prevent oversized scans.
Solutions
- Raise the accessibility scan limit setting (account/root-account setting governing exceeds_accessibility_scan_limit?) if scanning large courses is intended.
- Skip or batch the scan for oversized courses; scan a subset of content instead.
- Check course.exceeds_accessibility_scan_limit? before queueing and handle the refusal gracefully in the caller.
- Reduce course content size or archive unused content, then retry the scan.
Example fix
// before
Accessibility::CourseScanService.queue_course_scan(course) # raises for huge courses
// after
if course.exceeds_accessibility_scan_limit?
Rails.logger.info("Skipping accessibility scan for course #{course.id}: over scan limit")
else
Accessibility::CourseScanService.queue_course_scan(course)
end Defensive patterns
Strategy: validation
Validate before calling
if course.exceeds_accessibility_scan_limit?
return render json: { error: 'Course exceeds accessibility scan limit' }, status: :unprocessable_entity
end Type guard
def scan_eligible?(course) !course.exceeds_accessibility_scan_limit? end
Try / catch
begin Accessibility::CourseScanService.queue_course_scan(course) rescue Accessibility::ScanLimitExceededError flash[:warning] = 'This course is too large for an accessibility scan.' end
Prevention
- Check exceeds_accessibility_scan_limit? before queueing scans, especially in batch jobs.
- Raise the scan limit setting if large-course scans are a legitimate need.
- Scan large courses in content subsets instead of a whole-course scan.
When it happens
Trigger: Request an accessibility course scan (via API or UI) on a Course whose content size/count (e.g. number of pages/assignments/files, per exceeds_accessibility_scan_limit?) is above the configured scan limit, and no pending Progress with tag SCAN_TAG already exists for it.
Common situations: Very large courses (thousands of pages/items) triggering scans; instances with a low accessibility scan limit setting; scripts batch-queuing scans across all courses hitting the limit on the biggest ones.
Understand the failure class
Background: "File too large" / "file size exceeds limit" errors: why libraries cap file sizes and how to fix them — this error's family across 46 libraries.
Related errors
- [A11Y Scan] Skipped resource #
- [Accessibility::CategoryBreakdownService] dropping unknown…
- Caption cannot be empty.
- Element not found at path: #
- Invalid scope value. Valid options are: #
AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15).
Data as JSON: /api/errors/39cded7d95b2a55a.
Report an issue: GitHub.
Appendix: source
Thrown at app/services/accessibility/course_scan_service.rb:36
# with this program. If not, see <http://www.gnu.org/licenses/>.
class Accessibility::CourseScanService < ApplicationService
include Accessibility::Concerns::CourseStatisticsQueueable
SCAN_TAG = "course_accessibility_scan"
class ScanLimitExceededError < StandardError; end
def self.last_accessibility_course_scan(course)
Progress.where(tag: SCAN_TAG, context: course).last
end
def self.queue_course_scan(course)
progress = Progress.where(tag: SCAN_TAG, context_type: "Course", context_id: course.id).last
return progress if progress&.pending?
if course.exceeds_accessibility_scan_limit?
raise ScanLimitExceededError, "Course exceeds accessibility scan limit"
end
progress = Progress.create!(tag: SCAN_TAG, context: course)
n_strand = [SCAN_TAG, course.global_id]
singleton = "#{SCAN_TAG}_#{course.global_id}"
progress.process_job(self, :scan, { n_strand:, singleton: })
progress
end
def self.scan(progress)
service = new(course: progress.context)
service.scan_course
progress.set_results({})
progress.complete!
service.queue_course_statistics(progress.context)
rescue => e
progress.fail!View on GitHub (pinned to 1c9f0bb801)