padrino/padrino-framework · error

The email '# ' is already defined

Error message

The email '#{name}' is already defined

What it means

In the padrino-mailer DSL, each email :name do ... end block stores a proc in the mailer's messages hash keyed by that name. The email method raises when messages already has an entry for the name, preventing a second block from silently overwriting the first message definition.

Solutions

  1. Rename the second email block so every message name inside the mailer is unique
  2. If the intent was to replace a message, delete the old block instead of redefining it
  3. Run SampleMailer.messages.keys in a console to list defined names and find the collision

Example fix

# before — two blocks named :welcome in one mailer
email :welcome do ... end
email :welcome do ... end

# after
email :welcome do ... end
email :welcome_reminder do ... end
Defensive patterns

Strategy: validation

Validate before calling

# before declaring a message programmatically
raise ArgumentError, 'email :name already defined' if SomeMailer.messages.key?(name)

Type guard

def mailer_message_name_free?(mailer, name)
  !mailer.messages.key?(name)
end

Prevention

When it happens

Trigger: Declaring two email :welcome blocks in the same mailer; copy-pasting a message block and forgetting to rename it; code paths that declare the same email name twice while the mailer class is being defined or reopened.

Common situations: Copy-paste of an existing message as a starting point for a new one; merge conflicts where both branches add a message with the same name; refactoring that re-runs mailer declarations without reloading the class cleanly.

Related errors


AI-assisted analysis of padrino/padrino-framework@167044f3d5 (2026-08-23). Data as JSON: /api/errors/5445a72cd7f2851f. Report an issue: GitHub.

Appendix: source

Thrown at padrino-mailer/lib/padrino-mailer/base.rb:84

      # Defines a mailer object allowing the definition of various email
      # messages that can be delivered.
      #
      # @param [Symbol] name
      #   The name of this email message.
      # @param [Proc] block
      #   The message definition (i.e subject, to, from, locals).
      #
      # @example
      #   email :birthday do |name, age|
      #     subject "Happy Birthday!"
      #     to      'john@fake.com'
      #     from    'noreply@birthday.com'
      #     locals  name: name, age: age
      #     render 'birthday'
      #   end
      #
      def email(name, &block)
        raise "The email '#{name}' is already defined" if self.messages[name]
        self.messages[name] = proc { |*attrs|
          message = app.settings._padrino_mailer::Message.new(self.app)
          message.mailer_name = mailer_name
          message.message_name = name
          message.defaults = self.defaults if self.defaults.any?
          message.delivery_method(*delivery_settings)
          message.instance_exec(*attrs, &block)
          message
        }
      end
      alias message email

      # Defines the default attributes for a message in this mailer
      # (including app-wide defaults).
      #
      # @param [Hash] attributes
      #   The hash of message options to use as default.
      #

View on GitHub (pinned to 167044f3d5)