ruby/ruby · error · Gem::Exception
Unable to download '#{spec.full_name}'
Error message
Unable to download '#{spec.full_name}' What it means
Gem::Source::SpecificFile#download returns the wrapped file's path only when the passed spec == @spec, and Gem::Specification#== compares class plus name, version, and platform. The error means the spec handed to download describes a different gem (or a different version/platform) than the .gem file this source wraps — most often a dependency's spec routed to the wrong source.
Source
Thrown at lib/rubygems/source/specific_file.rb:41
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+.
#
# If +other+ is a SpecificFile from a different gem name +nil+ is returned.
#
# If +other+ is a SpecificFile from the same gem name the versions are
# compared using Gem::Version#<=>View on GitHub (pinned to 0e5b888e1c)
Solutions
- Call download with the source's own spec: src.download(src.spec)
- Guard before calling: skip the source unless spec == src.spec, and route other specs to sources that actually hold them
- For plain installs, use gem install ./foo-1.0.gem and let RubyGems pick dependencies from proper sources
Example fix
# before
specific = Gem::Source::SpecificFile.new("foo-1.0.gem")
specific.download(resolved_bar_spec) #=> Unable to download 'bar-2.0'
# after
cached = sources.find {|s| s.is_a?(Gem::Source::SpecificFile) && s.spec == spec }
path = cached ? cached.download(spec) : remote_source.download(spec) Defensive patterns
Strategy: type-guard
Type guard
# Gem::Specification#== compares name, version, platform (specification.rb) def specific_file_holds?(source, spec) spec.is_a?(Gem::Specification) && spec == source.spec end path = specific_file_holds?(src, spec) ? src.download(spec) : nil
Prevention
- Guard downloads with spec == source.spec before calling SpecificFile#download; only its own spec is accepted
- In custom resolvers, iterate sources and skip ones whose wrapped spec does not equal the requested spec
- Pass the source's own spec (source.spec) when you just need the file path for that gem
When it happens
Trigger: source.download(spec) where spec was resolved elsewhere (a dependency's spec) rather than the spec parsed from the wrapped .gem; version/platform differences between the requested spec and the file's spec.
Common situations: Custom installers/resolvers iterating sources and calling download with each candidate spec; platform mixups (requesting the ruby platform spec for a x86_64-linux .gem); version skew after rebuilding a gem without updating the caller.
Related errors
- 17
- unsupported URI scheme #{source_uri.scheme}
- Unable to find '#{name}'
- missing codepage argument
- unexpected debug option: %.*s\n
AI-assisted analysis of ruby/ruby@0e5b888e1c (2026-08-21).
Data as JSON: /api/errors/e116998580b5e1d6.
Report an issue: GitHub.