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
- Run the scan (SCAN_TAG Progress) for the course first and use the id of the resulting Progress record
- Verify the scan_id belongs to the same course whose YoutubeMigrationService instance you are using
- Check Progress.where(tag: 'youtube_embed_scan', context: course) to list valid scan ids
- 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
- Always obtain scan_id from the Progress record returned by the scan phase for the same course
- Never hard-code scan ids across environments
- Account for Progress row retention/cleanup between scan and convert
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
- Course not found
- Resource not found for type: #
- Resource not found in scan for key: #
- An institutional tag category did not pass validation
- Cannot validate existence for resource type: #
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_existsView on GitHub (pinned to 1c9f0bb801)