{"record":{"id":"c6820aeab287824a","repo":"instructure/canvas-lms","slug":"unrecognized-content-type-incoming-message-mime-type-inspect","errorCode":null,"errorMessage":"Unrecognized Content-Type: #{incoming_message.mime_type.inspect}","messagePattern":"Unrecognized Content-Type: #(.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"gems/incoming_mail_processor/lib/incoming_mail_processor/incoming_message_processor.rb","lineNumber":265,"sourceCode":"    end\n\n    private\n\n    def extract_body(incoming_message)\n      if incoming_message.multipart?\n        html_part = incoming_message.html_part\n        text_part = incoming_message.text_part\n\n        html_body = self.class.utf8ify(html_part.body.decoded, html_part.charset) if html_part\n        text_body = self.class.utf8ify(text_part.body.decoded, text_part.charset) if text_part\n      else\n        case incoming_message.mime_type\n        when \"text/plain\", nil\n          text_body = self.class.utf8ify(incoming_message.body.decoded, incoming_message.charset)\n        when \"text/html\"\n          html_body = self.class.utf8ify(incoming_message.body.decoded, incoming_message.charset)\n        else\n          raise \"Unrecognized Content-Type: #{incoming_message.mime_type.inspect}\"\n        end\n      end\n\n      if html_body && !text_body\n        text_body = self.class.html_to_text(html_body)\n      end\n\n      if text_body && !html_body\n        html_body = self.class.format_message(text_body).first\n      end\n\n      [text_body, html_body]\n    end\n\n    def report_stats(incoming_message, mailbox_account)\n      InstStatsd::Statsd.distributed_increment(\"incoming_mail_processor.incoming_message_processed.#{mailbox_account.escaped_address}\",\n                                               short_stat: \"incoming_mail_processor.incoming_message_processed\",\n                                               tags: { mailbox: mailbox_account.escaped_address })","sourceCodeStart":247,"sourceCodeEnd":283,"githubUrl":"https://github.com/instructure/canvas-lms/blob/1c9f0bb8013ed69c4f2efe11fd483025469b7e6c/gems/incoming_mail_processor/lib/incoming_mail_processor/incoming_message_processor.rb#L247-L283","documentation":"IncomingMessageProcessor#extract_body only understands text/plain, text/html, or a nil MIME type on incoming messages. Any other Content-Type (e.g. multipart variants, images, or exotic types surfacing from misparsed mail) has no extraction path and raises so the message can be handled by error processing instead of producing an empty body.","triggerScenarios":"Processing an inbound email whose top-level MIME type is neither text/plain nor text/html — commonly multipart/* that the mail library did not decompose, or messages with attachments as the primary part, messages with content types like application/* forwarded whole.","commonSituations":"Non-English mail clients emitting odd content types; emails where the parser fails to split multipart (malformed MIME boundaries); forwarded message/rfc822 bodies; HTML-only newsletters parsed as multipart/related without a text part handled upstream.","solutions":["Inspect the offending message's Content-Type header to confirm why it isn't text/plain or text/html.","Ensure the mail library (Mail gem) fully parses multipart messages so extract_body receives a leaf part, not the multipart container.","Fix malformed MIME boundaries upstream or reject/skip such messages in process_single error handling.","If a new legitimate type must be supported, extend the case statement to map it (e.g. decode HTML branch for multipart/related leaf parts)."],"exampleFix":"// before\n# raise \"Unrecognized Content-Type: multipart/related\"\n// after (in code that feeds extract_body)\nparts = incoming_message.multipart? ? incoming_message.text_part : incoming_message\nraise ArgumentError, 'no text part' if parts.nil?\nextract_body(parts)","handlingStrategy":"try-catch","validationCode":"mime = incoming_message.mime_type\nreturn :unsupported unless mime.nil? || %w[text/plain text/html].include?(mime)","typeGuard":"def supported_mime?(msg)\n  msg.mime_type.nil? || %w[text/plain text/html].include?(msg.mime_type)\nend","tryCatchPattern":"begin\n  processor.process_single(message)\nrescue RuntimeError => e\n  raise unless e.message.start_with?('Unrecognized Content-Type:')\n  mailbox.move_file(message.id, :failure) # route to failure folder for inspection\nend","preventionTips":["Let the Mail gem fully decompose multipart messages before extracting bodies.","Quarantine non-text messages to a failure folder instead of crashing the poll loop.","Log the Content-Type of rejected messages to spot recurring client patterns."],"tags":["mail","mime","parsing","unsupported-content-type"],"backgroundTag":"unsupported-enum-value","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"}