{"record":{"id":"7b7edf66ab262a79","repo":"hashie/hashie","slug":"you-are-setting-a-key-that-conflicts-with-a-built","errorCode":null,"errorMessage":"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.","messagePattern":"You are setting a key that conflicts with a built-in method #(.+?)##(.+?) #(.+?)\\. This can cause unexpected behavior when accessing the key as a property\\. You can still access the key via the #\\[\\] method\\.","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"lib/hashie/mash.rb","lineNumber":400,"sourceCode":"        duping ? val.dup : val\n      when ::Hash\n        val = val.dup if duping\n        self.class.new(val)\n      when ::Array\n        Array.new(val.map { |e| convert_value(e) })\n      else\n        val\n      end\n    end\n\n    private\n\n    def log_built_in_message(method_key)\n      return if self.class.disable_warnings?(method_key)\n\n      method_information = Hashie::Utils.method_information(method(method_key))\n\n      Hashie.logger.warn(\n        'You are setting a key that conflicts with a built-in method ' \\\n        \"#{self.class}##{method_key} #{method_information}. \" \\\n        'This can cause unexpected behavior when accessing the key as a ' \\\n        'property. You can still access the key via the #[] method.'\n      )\n    end\n\n    def log_collision?(method_key)\n      return unless method_key.is_a?(String) || method_key.is_a?(Symbol)\n      return unless respond_to?(method_key)\n\n      _, suffix = method_name_and_suffix(method_key)\n\n      (!suffix || suffix == '='.freeze) &&\n        !self.class.disable_warnings?(method_key) &&\n        !(regular_key?(method_key) || regular_key?(method_key.to_s))\n    end\n  end","sourceCodeStart":382,"sourceCodeEnd":418,"githubUrl":"https://github.com/hashie/hashie/blob/fde8e03a0a19da626576415223e4b002fc373967/lib/hashie/mash.rb#L382-L418","documentation":"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].","triggerScenarios":"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.","commonSituations":"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.","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)."],"exampleFix":"# before\nconfig = Hashie::Mash.new(response)  # warns when response has \"merge\"/\"zip\"/\"key\"\nmerged = config.merge                 # calls Hash#merge, not your key\n\n# after\nclass Config < Hashie::Mash\n  disable_warnings :merge, :zip, :key\nend\nconfig = Config.new(response)\nmerged = config[:merge]               # always reads the stored key","handlingStrategy":"validation","validationCode":"# mirrors Hashie's own log_collision? guard (mash.rb:408) before writing\ndef colliding_key?(mash, key)\n  key = key.to_s\n  mash.respond_to?(key) && !mash.key?(key)\nend\n\npayload.each { |k, _v| warn \"mash key collision: #{k}\" if colliding_key?(mash, k) }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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."],"tags":["ruby","hashie","mash","method-collision","logging","warnings"],"backgroundTag":"method-name-collision","analyzedSha":"fde8e03a0a19da626576415223e4b002fc373967","analyzedAt":"2026-08-23T14:54:52.149Z","schemaVersion":2},"datasetVersion":"2026-08-23T16:17:53.355Z"}