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
endView on GitHub (pinned to fde8e03a0a)
Solutions
- 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.
- Silence the warning for known keys with a subclass: class Config < Hashie::Mash; disable_warnings :merge, :zip; end.
- Or use the built-in quiet subclass factory: Hashie::Mash.quiet(:merge).new(payload) (no arguments disables all collision warnings).
- Rename or re-map the colliding keys in the payload before loading it into the Mash.
- 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
- Treat any key where mash.respond_to?(key) as []-only; never read or write it as a property.
- Disable warnings per key in a dedicated subclass instead of globally, so new collisions still surface.
- Add a spec that checks inbound payload keys against Hashie::Mash instance methods.
- Read hashie's UPGRADING.md when upgrading — collision detection and logging behavior changed across versions.
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.