ruby/ruby · error · Gem::Exception

Unable to find '#{name}'

Error message

Unable to find '#{name}'

What it means

Gem::Source::SpecificFile wraps exactly one .gem file; fetch_spec answers only for its own name tuple (@name) and raises for any other. Hitting it means the resolver/caller asked this single-file source for a gem it cannot possibly serve — e.g. a dependency was routed to the SpecificFile source of an unrelated gem, or the tuple (platform/version) differs from the file's.

Source

Thrown at lib/rubygems/source/specific_file.rb:36

    @path = ::File.expand_path(file)

    @package = Gem::Package.new @path
    @spec = @package.spec
    @name = @spec.name_tuple
  end

  ##
  # The Gem::Specification extracted from this .gem.

  attr_reader :spec

  def load_specs(*a) # :nodoc:
    [@name]
  end

  def fetch_spec(name) # :nodoc:
    return @spec if name == @name
    raise Gem::Exception, "Unable to find '#{name}'"
  end

  def download(spec, dir = nil) # :nodoc:
    return @path if spec == @spec
    raise Gem::Exception, "Unable to download '#{spec.full_name}'"
  end

  def pretty_print(q) # :nodoc:
    q.object_group(self) do
      q.group 2, "[SpecificFile:", "]" do
        q.breakable
        q.text @path
      end
    end
  end

  ##
  # Orders this source against +other+.

View on GitHub (pinned to 0e5b888e1c)

Solutions

  1. Provide a source that can serve the requested gem: add the default remote source, or wrap the dependency's own .gem in its own Gem::Source::SpecificFile
  2. Compare tuples before calling: source.load_specs.first vs. the requested name/version/platform, and fix mismatches
  3. Install dependencies first (gem install dep -v x.y.z) so nothing needs to be fetched from the single-file source

Example fix

# before
specific = Gem::Source::SpecificFile.new("foo-1.0.gem")
specific.fetch_spec(Gem::NameTuple.new("bar", Gem::Version.new("2.0"), "ruby")) #=> Unable to find 'bar'

# after: only ask a source for what it holds
foo_tuple = specific.load_specs.first
specific.fetch_spec(foo_tuple)  # => foo's spec
Defensive patterns

Strategy: validation

Validate before calling

specific = Gem::Source::SpecificFile.new("foo-1.0.gem")
owned = specific.load_specs.first  # the one tuple this source serves
raise "this source only provides #{owned.full_name}" unless name == owned
specific.fetch_spec(name)

Type guard

def specific_file_serves?(source, name_tuple)
  source.load_specs.first == name_tuple
end

Prevention

When it happens

Trigger: gem install ./foo.gem (or custom resolvers using SpecificFile) where a transitive dependency gets resolved against this source; tuple mismatch such as requesting the "ruby" platform tuple while the file provides x86_64-linux (or vice versa); name differences after renaming a gem.

Common situations: Installing a .gem with unmet dependencies using local-only sources; custom installer code that mixes one SpecificFile into the source list; platform-specific .gem files requested with a different platform tuple.

Related errors


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