{"record":{"id":"600c91eaf8b4807c","repo":"instructure/canvas-lms","slug":"unsupported-content-type","errorCode":null,"errorMessage":"Unsupported content type","messagePattern":"Unsupported content type","errorType":"validation","errorClass":"UnsupportedContentType","httpStatus":null,"severity":"error","filePath":"app/services/study_assist.rb","lineNumber":174,"sourceCode":"    def resolve_page(page_id)\n      page = @course.wiki_pages.not_deleted.find_by(url: page_id)\n      raise ContentUnavailable, \"Page not found\" if page.nil?\n      raise ContentUnavailable, \"Page access denied\" unless page.grants_right?(@user, :read)\n\n      shard_safe_key = shard_safe_cache_key_for(page)\n      text = Rails.cache.fetch(text_cache_key_for(:page, shard_safe_key), expires_in: TEXT_CACHE_TTL) do\n        html_to_text(page.body.to_s)\n      end\n\n      Content.new(kind: :page, id: page.id, cache_key_with_version: shard_safe_key, text:)\n    end\n\n    def resolve_file(file_id)\n      attachment = @course.attachments.find_by(id: file_id)\n      raise ContentUnavailable, \"File not found\" if attachment.nil? || attachment.deleted?\n      raise ContentUnavailable, \"File access denied\" unless attachment.grants_right?(@user, :read)\n      raise ContentUnavailable, \"File is locked\" if attachment.locked_for?(@user, check_policies: true)\n      raise UnsupportedContentType unless supported_attachment?(attachment)\n      raise ContentTooLarge, \"File exceeds #{MAX_FILE_BYTES} byte limit\" if attachment.size && attachment.size > MAX_FILE_BYTES\n\n      shard_safe_key = shard_safe_cache_key_for(attachment)\n      text = Rails.cache.fetch(text_cache_key_for(:file, shard_safe_key), expires_in: TEXT_CACHE_TTL) do\n        extract_attachment_text(attachment)\n      end\n\n      raise ContentUnavailable, \"No text available for file\" if text.blank?\n\n      Content.new(kind: :file, id: attachment.id, cache_key_with_version: shard_safe_key, text:)\n    end\n\n    def supported_attachment?(attachment)\n      return true if attachment.content_type&.start_with?(\"text/\")\n\n      ACCEPTED_FILE_MIMETYPES.include?(attachment.content_type)\n    end\n","sourceCodeStart":156,"sourceCodeEnd":192,"githubUrl":"https://github.com/instructure/canvas-lms/blob/1c9f0bb8013ed69c4f2efe11fd483025469b7e6c/app/services/study_assist.rb#L156-L192","documentation":"StudyAssist::UnsupportedContentType is raised by resolve_file when supported_attachment?(attachment) is false. Only certain file types (e.g. text/PDF-like attachments) have text extraction support; images, media, spreadsheets, or unknown MIME types are rejected.","triggerScenarios":"Calling #call with file_id pointing to an attachment whose content type or extension is not in the supported set (e.g. .png, .mp4, .zip, .xlsx).","commonSituations":"User selects an image or media file in the UI while expecting AI analysis; newer file types not yet whitelisted in supported_attachment?; files with missing/misreported MIME content_type.","solutions":["Only pass attachments of supported types (check supported_attachment? / the whitelist in study_assist.rb)","Convert or transcribe unsupported files (e.g. OCR images) before calling","Extend supported_attachment? to cover additional types if extraction is feasible","Filter file pickers client-side to supported MIME types"],"exampleFix":"// before\nStudyAssist.new(course:, user:, prompt:, file_id: image_attachment.id).call\n// after\nunless StudyAssist.supported_attachment?(image_attachment)\n  return render json: { error: 'unsupported file type' }, status: :unprocessable_entity\nend\nStudyAssist.new(course:, user:, prompt:, file_id: image_attachment.id).call","handlingStrategy":"validation","validationCode":"raise StudyAssist::UnsupportedContentType unless course.attachments.find_by(id: file_id)&.then { |a| StudyAssist.respond_to?(:supported_attachment?) ? StudyAssist.send(:supported_attachment?, a) : SUPPORTED_TYPES.include?(a.content_type) }","typeGuard":"null","tryCatchPattern":"begin\n  StudyAssist.new(course:, user:, prompt:, file_id:).call\nrescue StudyAssist::UnsupportedContentType\n  render json: { error: 'unsupported file type' }, status: :unprocessable_entity\nend","preventionTips":["Whitelist supported MIME types in file pickers","Check supported_attachment? logic before enabling files","Validate content_type during upload pipelines"],"tags":["ruby","study-assist","file-type","unsupported-content"],"backgroundTag":"unsupported-operation","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"}