ruby/ruby · error · ArgumentError

#{self} and #{other} have different names

Error message

#{self} and #{other} have different names

What it means

Gem::Dependency#merge unions the requirement lists of two dependencies and is only defined for dependencies on the same gem. Merging dependencies whose names differ raises ArgumentError ('<self> and <other> have different names').

Source

Thrown at lib/rubygems/dependency.rb:259

  # Does this dependency match +spec+?
  #
  # NOTE:  This is not a convenience method.  Unlike #match? this method
  # returns true when +spec+ is a prerelease version even if this dependency
  # is not a prerelease dependency.

  def matches_spec?(spec)
    return false unless name === spec.name
    return true  if requirement.none?

    requirement.satisfied_by?(spec.version)
  end

  ##
  # Merges the requirements of +other+ into this dependency

  def merge(other)
    unless name == other.name
      raise ArgumentError,
            "#{self} and #{other} have different names"
    end

    default = Gem::Requirement.default
    self_req = requirement
    other_req = other.requirement

    return self.class.new name, self_req  if other_req == default
    return self.class.new name, other_req if self_req  == default

    self.class.new name, self_req.as_list.concat(other_req.as_list)
  end

  def matching_specs(platform_only = false)
    matches = Gem::Specification.find_all_by_name(name, requirement)

    if platform_only
      matches.reject! do |spec|

View on GitHub (pinned to 0e5b888e1c)

Solutions

  1. Group dependencies by name (hash keyed by d.name) and merge only matching pairs.
  2. Guard the call site: merge only `if a.name == b.name`, otherwise keep both dependencies.
  3. Fix the upstream pairing logic that produced mismatched couples.

Example fix

# before
merged = deps[i].merge(other_deps[i])
# after
others = other_deps.to_h { |d| [d.name, d] }
merged = deps.map { |d| others.key?(d.name) ? d.merge(others[d.name]) : d }
Defensive patterns

Strategy: validation

Validate before calling

raise ArgumentError, "#{a.name} and #{b.name} differ" unless a.name == b.name
a.merge(b)

Prevention

When it happens

Trigger: `dep.merge(other)` where dep.name != other.name — resolution/merge code that pairs dependencies positionally or by index instead of by name, or a generic merge helper applied to heterogeneous dependency lists.

Common situations: Homegrown resolvers combining two gemfiles/lockfiles; refactors assuming parallel arrays stay aligned; deduplication logic that merges whatever is next in the list.

Related errors


AI-assisted analysis of ruby/ruby@0e5b888e1c (2026-08-21). Data as JSON: /api/errors/4bdbd93e1772f69e. Report an issue: GitHub.