hashie/hashie · warning

You are setting a key that conflicts with a built-in method

Error message

You are setting a key that conflicts with a built-in method #{self.class}##{method_key} #{method_information}. This can cause unexpected behavior when accessing the key as a property. You can still access the key via the #[] method.

What it means

Hashie::Mash exposes hash keys as method accessors, so storing a key whose name collides with a method the mash already responds to (Hash/Mash built-ins such as key, merge, update, zip, size, store, dig, class) is unsafe: mash.merge would invoke Hash#merge instead of returning your value. custom_writer — aliased as []= and backing every property writer — calls log_built_in_message (lib/hashie/mash.rb:395-406) whenever log_collision? (lib/hashie/mash.rb:408-417) detects such a name. This is a Hashie.logger.warn message, not an exception: the key is still stored and stays readable via mash[:key].

Source

Thrown at lib/hashie/mash.rb:400

        duping ? val.dup : val
      when ::Hash
        val = val.dup if duping
        self.class.new(val)
      when ::Array
        Array.new(val.map { |e| convert_value(e) })
      else
        val
      end
    end

    private

    def log_built_in_message(method_key)
      return if self.class.disable_warnings?(method_key)

      method_information = Hashie::Utils.method_information(method(method_key))

      Hashie.logger.warn(
        'You are setting a key that conflicts with a built-in method ' \
        "#{self.class}##{method_key} #{method_information}. " \
        'This can cause unexpected behavior when accessing the key as a ' \
        'property. You can still access the key via the #[] method.'
      )
    end

    def log_collision?(method_key)
      return unless method_key.is_a?(String) || method_key.is_a?(Symbol)
      return unless respond_to?(method_key)

      _, suffix = method_name_and_suffix(method_key)

      (!suffix || suffix == '='.freeze) &&
        !self.class.disable_warnings?(method_key) &&
        !(regular_key?(method_key) || regular_key?(method_key.to_s))
    end
  end

View on GitHub (pinned to fde8e03a0a)

Solutions

  1. Access conflicting keys only through []: value = mash[:merge]. Never read or write them as properties; note the warning fires on writes too (both mash.merge= and mash[:merge] =), but the value is stored correctly.
  2. Silence the warning for known keys with a subclass: class Config < Hashie::Mash; disable_warnings :merge, :zip; end.
  3. Or use the built-in quiet subclass factory: Hashie::Mash.quiet(:merge).new(payload) (no arguments disables all collision warnings).
  4. Rename or re-map the colliding keys in the payload before loading it into the Mash.
  5. Before adopting a payload schema, check its keys against Mash methods: mash.respond_to?(key).

Example fix

# before
config = Hashie::Mash.new(response)  # warns when response has "merge"/"zip"/"key"
merged = config.merge                 # calls Hash#merge, not your key

# after
class Config < Hashie::Mash
  disable_warnings :merge, :zip, :key
end
config = Config.new(response)
merged = config[:merge]               # always reads the stored key
Defensive patterns

Strategy: validation

Validate before calling

# mirrors Hashie's own log_collision? guard (mash.rb:408) before writing
def colliding_key?(mash, key)
  key = key.to_s
  mash.respond_to?(key) && !mash.key?(key)
end

payload.each { |k, _v| warn "mash key collision: #{k}" if colliding_key?(mash, k) }

Prevention

When it happens

Trigger: mash.zip = [1, 2] or mash['merge'] = x — property writers and []= both route through custom_writer (lib/hashie/mash.rb:135-141); Hashie::Mash.new(payload), update, or deep_merge! with payload keys like 'key', 'keys', 'merge', 'zip', 'update', 'size', 'store', 'dig', 'hash', 'class'; fires only when the mash respond_to?(key) and the key is not already a regular stored key.

Common situations: Wrapping third-party API/JSON responses in Mash when they contain keys like 'merge', 'size', or 'class'; settings classes built on Hashie::Mash (SettingsLogic-style) that start logging these warnings after new keys appear or hashie is upgraded; log-based alerting flagging the warning; a latent bug where code later reads mash.zip and gets Enumerable#zip behavior instead of the stored value.

Related errors


AI-assisted analysis of hashie/hashie@fde8e03a0a (2026-08-23). Data as JSON: /api/errors/7b7edf66ab262a79. Report an issue: GitHub.