Rails mailer error with inline attachment
email, ruby, ruby-on-rails, ruby-on-rails-3
Solution
I looked at the `mail` source.
This error can only occur if the content id field is nil. However calling `.url` should be setting the content id to an empty string unless `has_content_id?` is returning true, meaning there's already a content id field in the multipart header.
This is not happening, so we must have a strange case where the header object is reporting `has_content_id?` true yet is returning a `content_id` of `nil`.
Try setting the content id field explicitly just after you set the graphic.
attachments['visionamos.png'].header['content-id'] = 'logo.graphic'
If this works, there's still the puzzle of why it's necessary. Did you make any other changes to mailer configuration or code? Did you upgrade any gems?
Addition responding to question edit
The header parser seems to be failing because there are spaces in the id `...@MacBook Pro de Ruben.mail`. Try re-naming the computer with no spaces! I guess this constitutes a bug in `mail`. Spaces should be elided or replaced with a legal character.
My guess is that this will also fix the original problem, and you won't need to set the `content-id` manually any more. Hence another guess: you changed machine name or moved development to a new machine. and that's when the bug appeared!
Problem
I have a very rare behavior in Action Mailer, I had implement a mailer action like 5 months ago and it was working, but yesterday, for some strange reason, it crashed. The problem I have a mail layout, in order to use it in all my emails, in it I render an image that is attached previously by a before filter Layout = `app/views/layouts/email.html.erb` ``` <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Visionamos</title> <link rel="stylesheet" type="text/css" href=<%="/assets/email.css" %>> </head> <body> <table> <tr> <td id="head"> <table> <tr class="image"> <td><%= image_tag(attachments['visionamos.png'].url) %></td> ... .. . ``` User Mailer = `app/mailers/users.rb` ``` class UsuariosMailer < ActionMailer::Base include AbstractController::Callbacks # include controller callbacks default :from => "monitoreo@visionamos.com" layout "mail" #Set email layout before_filter :add_inline_attachments! # Add image header for all actions def otp_password(user, otp_key) @usuario = user @code = otp_key email_with_name = "#{@usuario.nombre} <#{@usuario.email}>" mail(:to => email_with_name, :subject => "One time password, Plataforma Visionamos") end private def add_inline_attachments! attachments.inline['visionamos.png'] = File.read("#{Rails.root}/app/assets/images/visionamos.png") end end ``` Now, when I try to send the email I'm, getting this error ``` NoMethodError - undefined method `match' for nil:NilClass: mail (2.5.4) lib/mail/utilities.rb:112:in `unbracket' mail (2.5.4) lib/mail/part.rb:29:in `cid' mail (2.5.4) lib/mail/part.rb:33:in `url' app/views/layouts/mail.html.erb:13:in `_app_views_layouts_mail_html_erb__573848672563180413_70191451095440' <td><%= image_tag(attachments['visionamos.png'].url) %></td> ``` But the image is attached to the email ``` >> attachments['visionamos.png'] => #<Mail::Part:70191451538040, Multipart: false, Headers: <Content-Type: image/png; filename="visionamos.png">, <Content-Transfer-Encoding: binary>, <Content-Disposition: inline; filename="visionamos.png">, <content-id: >> ``` My DevEnv Mac with Maverics Ruby 2.0 + Rails 3.2.16 Plus - The email is working in my amazon ec2 instance, in my coworkers environments (ubuntu and mac) - If I delete the image_tag method in layout, the email is sent and the image is show as attachment, no inline Update!!! I've tried @Gene solution but even the email is sent, the images are normal attachments, no inline, so looking deeply, I found this ``` >> attachments.inline['visionamos.png'].header => #<Mail::Header:0x00000106cf6870 @errors=[], @charset=nil, @raw_source="", @fields=[#<Mail::Field:0x00000106cf60c8 @field=#<Mail::ContentTypeField:0x00000106cf5fd8 @charset=nil, @main_type="image", @sub_type="png", @parameters={"filename"=>"visionamos.png"}, @name="Content-Type", @length=nil, @tree=nil, @element=#<Mail::ContentTypeElement:0x00000106cf5d30 @main_type="image", @sub_type="png", @parameters=[{"filename"=>"visionamos.png"}]>, @value="image/png; filename=\"visionamos.png\"", @filename="visionamos.png">, @field_order_id=23>, #<Mail::Field:0x00000106d17390 @field=#<Mail::ContentTransferEncodingField:0x00000106d172a0 @charset=nil, @name="Content-Transfer-Encoding", @length=nil, @tree=nil, @element=#<Mail::ContentTransferEncodingElement:0x00000106d16ff8 @encoding="binary">, @value="binary">, @field_order_id=24>, #<Mail::Field:0x00000106d14a78 @field=#<Mail::ContentDispositionField:0x00000106d14960 @charset=nil, @name="Content-Disposition", @length=nil, @tree=nil, @element=#<Mail::ContentDispositionElement:0x00000106d145c8 @disposition_type="inline", @parameters=[{"filename"=>"visionamos.png"}]>, @value="inline; filename=\"visionamos.png\"", @parameters={"filename"=>"visionamos.png"}, @filename="visionamos.png">, @field_order_id=26>, #<Mail::Field:0x00000106d3e8f0 @field=#<Mail::UnstructuredField:0x00000106d5ef60 @errors=[["content-id", nil, #<Mail::Field::ParseError: Mail::MessageIdsElement can not parse |<52fe636fae8a6_686085098c087130@MacBook Pro de Ruben.mail>| ``` Reason was: Expected one of !, #, $, %, &, ', *, +, -, /, =, ?, ^, _, `, {, |, }, ~, @, ., ", > at line 1, column 40 (byte 40) after <52fe636fae8a6_686085098c087130@MacBook>]], @charset=#, @name="content-id", @length=nil, @tree=nil, @element=nil, @value="">, @field_order_id=100>]> The interesting part is ``` #<Mail::Field::ParseError: Mail::MessageIdsElement can not parse |<52fe636fae8a6_686085098c087130@MacBook Pro de Ruben.mail>| Reason was: Expected one of !, #, $, %, &, ', *, +, -, /, =, ?, ^, _, `, {, |, }, ~, @, ., ", > at line 1, column 40 (byte 40) after <52fe636fae8a6_686085098c087130@MacBook>]], ```