padrino/padrino-framework · error

The email '#{name}' 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.

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)

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.