instructure/canvas-lms · error · EmbedNotFoundError

Scan not found for id: #

Error message

Scan not found for id: #{scan_id}

What it means

validate_scan_exists! looks up the youtube_embed_scan Progress record for the course via YoutubeMigrationService.find_scan. If no Progress with that scan_id exists for the course, ActiveRecord::RecordNotFound is rescued and re-raised as EmbedNotFoundError. It guards the embed-conversion flow from operating on a missing/stale scan.

Solutions

  1. Run the scan (SCAN_TAG Progress) for the course first and use the id of the resulting Progress record
  2. Verify the scan_id belongs to the same course whose YoutubeMigrationService instance you are using
  3. Check Progress.where(tag: 'youtube_embed_scan', context: course) to list valid scan ids
  4. If the scan is gone, re-scan and retry conversion with the new scan_id

Example fix

// before
service.convert_embed(stale_scan_id, embed)
// after
scan = Progress.where(tag: 'youtube_embed_scan', context: course).last
raise 'no scan available; run the scan first' unless scan
service.convert_embed(scan.id, embed)
Defensive patterns

Strategy: try-catch

Validate before calling

scan = Progress.where(tag: 'youtube_embed_scan', context: course).find_by(id: scan_id)
raise 'scan_id does not belong to this course' unless scan

Type guard

def valid_scan?(course, scan_id)
  scan_id.is_a?(Integer) && Progress.where(tag: 'youtube_embed_scan', context: course).exists?(id: scan_id)
end

Try / catch

begin
  service.convert_embed(scan_id, embed)
rescue YoutubeMigrationService::EmbedNotFoundError => e
  Rails.logger.warn("scan missing: #{e.message}; re-running scan")
  YoutubeMigrationService.run_scan(course)
end

Prevention

When it happens

Trigger: Calling convert_embed (or validate_scan_exists!) with a scan_id that was never created, belongs to a different course, or whose Progress record was deleted/expired.

Common situations: Reusing a scan id from another course or shard; scan Progress purged between scan and convert phases; client passing a hard-coded or fabricated scan_id; job retry after the Progress row was removed.

Understand the failure class

Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.

Related errors


AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15). Data as JSON: /api/errors/38876069fd63be97. Report an issue: GitHub.

Appendix: source

Thrown at app/services/youtube_migration_service.rb:143

    else
      resource_group_key || YoutubeMigrationService.generate_resource_key(resource_type, id)
    end
  end

  def self.generate_resource_key(type, id)
    "#{type}|#{id}"
  end

  attr_accessor :course

  def initialize(course)
    self.course = course
  end

  def validate_scan_exists!(scan_id)
    YoutubeMigrationService.find_scan(course, scan_id)
  rescue ActiveRecord::RecordNotFound
    raise EmbedNotFoundError, "Scan not found for id: #{scan_id}"
  end

  def validate_embed_exists_in_scan!(scan_id, embed)
    scan = YoutubeMigrationService.find_scan(course, scan_id)
    resource_group_key = resource_group_key_for(embed)

    return if scan.results.blank? || scan.results[:resources].blank?

    resource = scan.results[:resources][resource_group_key]
    raise EmbedNotFoundError, "Resource not found in scan for key: #{resource_group_key}" if resource.blank?

    embed_exists = resource[:embeds].any? do |scan_embed|
      scan_embed[:src] == embed[:src] &&
        scan_embed[:field].to_s == embed[:field].to_s &&
        scan_embed[:resource_type] == embed[:resource_type]
    end

    raise EmbedNotFoundError, "Embed not found in scan for resource: #{resource_group_key}" unless embed_exists

View on GitHub (pinned to 1c9f0bb801)