instructure/canvas-lms · error · ResourceNotFoundError

Cannot validate existence for resource type: #

Error message

Cannot validate existence for resource type: #{resource_type}

What it means

validate_resource_exists! handles each supported resource type with a find, but falls through to an else branch for any type that passed the supported check yet has no explicit validation branch — raising ResourceNotFoundError 'Cannot validate existence'. This indicates the supported-type list and the case statement are out of sync.

Solutions

  1. Check the resource_type against the case statement in validate_resource_exists! and add a `when` branch that finds/validates it
  2. If the type is New Quizzes, confirm it exactly matches a NEW_QUIZZES_RESOURCES entry so the early `return true` short-circuits
  3. Remove the type from SUPPORTED_RESOURCES if it should not be converted
  4. Wrap convert_embed in rescue ResourceNotFoundError and handle unsupported-to-validate types gracefully

Example fix

// before
raise ResourceNotFoundError, "Cannot validate existence for resource type: #{resource_type}"
// after
when "DiscussionEntry"
  DiscussionEntry.find(resource_id)
else
  raise ResourceNotFoundError, "Cannot validate existence for resource type: #{resource_type}"
Defensive patterns

Strategy: try-catch

Validate before calling

KNOWN_BRANCHES = %w[WikiPage Quizzes::Quiz Quizzes::QuizQuestion AssessmentQuestion DiscussionTopic Announcement DiscussionEntry CalendarEvent Assignment CourseSyllabus Course]
raise 'type has no validate_resource_exists! branch' unless KNOWN_BRANCHES.include?(embed[:resource_type]) || YoutubeMigrationService::NEW_QUIZZES_RESOURCES.include?(embed[:resource_type])

Try / catch

begin
  service.convert_embed(scan_id, embed)
rescue YoutubeMigrationService::ResourceNotFoundError => e
  Rails.logger.error("validator gap: #{e.message}")
end

Prevention

When it happens

Trigger: convert_embed with a resource_type in SUPPORTED_RESOURCES/NEW_QUIZZES_RESOURCES (or newly added) that has no `when` branch in validate_resource_exists!, such as types added to the list without updating the validator.

Common situations: Version drift: a resource type added to SUPPORTED_RESOURCES in one release but the validate case statement not updated; plugin-injected types; NEW_QUIZZES variants expected to be short-circuited but passed under an unexpected name.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


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

Appendix: source

Thrown at app/services/youtube_migration_service.rb:212

    when "Assignment"
      course.assignments.find(resource_id)
    when "DiscussionTopic", "Announcement"
      course.discussion_topics.find(resource_id)
    when "DiscussionEntry"
      DiscussionEntry.find(resource_id)
    when "CalendarEvent"
      course.calendar_events.find(resource_id)
    when "Quizzes::Quiz"
      course.quizzes.find(resource_id)
    when "Quizzes::QuizQuestion"
      Quizzes::QuizQuestion.find(resource_id)
    when "AssessmentQuestion"
      AssessmentQuestion.find(resource_id)
    when "CourseSyllabus", "Course"
      # For syllabus, the resource_id is the course id
      raise ResourceNotFoundError, "Course not found" unless course.id == resource_id
    else
      raise ResourceNotFoundError, "Cannot validate existence for resource type: #{resource_type}"
    end
  rescue ActiveRecord::RecordNotFound
    raise ResourceNotFoundError, "Resource not found for type: #{resource_type}, id: #{resource_id}"
  end

  def convert_embed(scan_id, embed, user_uuid: nil)
    validate_scan_exists!(scan_id)
    validate_supported_resource!(embed[:resource_type])

    resource_group_key = embed[:resource_group_key] || YoutubeMigrationService.generate_resource_key(embed[:resource_type], embed[:id])
    validate_resource_group_key!(resource_group_key)
    validate_embed_exists_in_scan!(scan_id, embed)
    validate_resource_exists!(embed[:resource_type], embed[:id])

    message = YoutubeMigrationService.generate_resource_key(embed[:resource_type], embed[:id])
    # TODO: Something will listen on this creation
    convert_progress = Progress.create!(tag: CONVERT_TAG, context: course, message:, results: { original_embed: embed })

View on GitHub (pinned to 1c9f0bb801)