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

  1. Raise the accessibility scan limit setting (account/root-account setting governing exceeds_accessibility_scan_limit?) if scanning large courses is intended.
  2. Skip or batch the scan for oversized courses; scan a subset of content instead.
  3. Check course.exceeds_accessibility_scan_limit? before queueing and handle the refusal gracefully in the caller.
  4. 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

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


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)