{"record":{"id":"40fcf02184e76c49","repo":"instructure/canvas-lms","slug":"cannot-validate-existence-for-resource-type-resource-type","errorCode":null,"errorMessage":"Cannot validate existence for resource type: #{resource_type}","messagePattern":"Cannot validate existence for resource type: #(.+?)","errorType":"exception","errorClass":"ResourceNotFoundError","httpStatus":400,"severity":"error","filePath":"app/services/youtube_migration_service.rb","lineNumber":212,"sourceCode":"    when \"Assignment\"\n      course.assignments.find(resource_id)\n    when \"DiscussionTopic\", \"Announcement\"\n      course.discussion_topics.find(resource_id)\n    when \"DiscussionEntry\"\n      DiscussionEntry.find(resource_id)\n    when \"CalendarEvent\"\n      course.calendar_events.find(resource_id)\n    when \"Quizzes::Quiz\"\n      course.quizzes.find(resource_id)\n    when \"Quizzes::QuizQuestion\"\n      Quizzes::QuizQuestion.find(resource_id)\n    when \"AssessmentQuestion\"\n      AssessmentQuestion.find(resource_id)\n    when \"CourseSyllabus\", \"Course\"\n      # For syllabus, the resource_id is the course id\n      raise ResourceNotFoundError, \"Course not found\" unless course.id == resource_id\n    else\n      raise ResourceNotFoundError, \"Cannot validate existence for resource type: #{resource_type}\"\n    end\n  rescue ActiveRecord::RecordNotFound\n    raise ResourceNotFoundError, \"Resource not found for type: #{resource_type}, id: #{resource_id}\"\n  end\n\n  def convert_embed(scan_id, embed, user_uuid: nil)\n    validate_scan_exists!(scan_id)\n    validate_supported_resource!(embed[:resource_type])\n\n    resource_group_key = embed[:resource_group_key] || YoutubeMigrationService.generate_resource_key(embed[:resource_type], embed[:id])\n    validate_resource_group_key!(resource_group_key)\n    validate_embed_exists_in_scan!(scan_id, embed)\n    validate_resource_exists!(embed[:resource_type], embed[:id])\n\n    message = YoutubeMigrationService.generate_resource_key(embed[:resource_type], embed[:id])\n    # TODO: Something will listen on this creation\n    convert_progress = Progress.create!(tag: CONVERT_TAG, context: course, message:, results: { original_embed: embed })\n","sourceCodeStart":194,"sourceCodeEnd":230,"githubUrl":"https://github.com/instructure/canvas-lms/blob/1c9f0bb8013ed69c4f2efe11fd483025469b7e6c/app/services/youtube_migration_service.rb#L194-L230","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Check the resource_type against the case statement in validate_resource_exists! and add a `when` branch that finds/validates it","If the type is New Quizzes, confirm it exactly matches a NEW_QUIZZES_RESOURCES entry so the early `return true` short-circuits","Remove the type from SUPPORTED_RESOURCES if it should not be converted","Wrap convert_embed in rescue ResourceNotFoundError and handle unsupported-to-validate types gracefully"],"exampleFix":"// before\nraise ResourceNotFoundError, \"Cannot validate existence for resource type: #{resource_type}\"\n// after\nwhen \"DiscussionEntry\"\n  DiscussionEntry.find(resource_id)\nelse\n  raise ResourceNotFoundError, \"Cannot validate existence for resource type: #{resource_type}\"","handlingStrategy":"try-catch","validationCode":"KNOWN_BRANCHES = %w[WikiPage Quizzes::Quiz Quizzes::QuizQuestion AssessmentQuestion DiscussionTopic Announcement DiscussionEntry CalendarEvent Assignment CourseSyllabus Course]\nraise 'type has no validate_resource_exists! branch' unless KNOWN_BRANCHES.include?(embed[:resource_type]) || YoutubeMigrationService::NEW_QUIZZES_RESOURCES.include?(embed[:resource_type])","typeGuard":null,"tryCatchPattern":"begin\n  service.convert_embed(scan_id, embed)\nrescue YoutubeMigrationService::ResourceNotFoundError => e\n  Rails.logger.error(\"validator gap: #{e.message}\")\nend","preventionTips":["When adding a type to SUPPORTED_RESOURCES, add its validate_resource_exists! branch in the same commit","Add a test asserting every supported type has a when branch","Report this error as a bug — it signals list/validator drift"],"tags":["ruby","validation","invariant","migration"],"backgroundTag":"internal-invariant-violation","analyzedSha":"1c9f0bb8013ed69c4f2efe11fd483025469b7e6c","analyzedAt":"2026-09-15T20:33:18.891Z","contentChangedAt":"2026-09-15T20:33:18.891Z","schemaVersion":2},"datasetVersion":"2026-09-23T02:17:17.105Z"}