Bug #19238

open fails for file path when second argument is a hash

Added by dkinzer (David Kinzer) 6 months ago. Updated about 1 month ago.

Target version:


I upgraded one of my projects to ruby 3.1.3 and I found that now throws an error when passed a second argument when the first argument is a file path.

When the first argument is a URL, then will work as expected.

I was able to replicate this issue in all 3.x versions including the latest so it's an issue that was introduce with the release of 3.0

I found it convenient that, {}), worked regardless of wether uri was a file path or a URL because it meant I did not have to add logic for varying cases. When the uri argument was a file path would simply open up the file and disregard the hash options params. But now I have to add that logic myself which is not as clean looking.

Below is an example of the error. It's quite easy to reproduce on any version of ruby 3.x"spec/fixtures/blogs.json", {})
/Users/dkinzer/.rbenv/versions/3.1.3/lib/ruby/3.1.0/open-uri.rb:31:in `initialize': no implicit conversion of Hash into String (TypeError)
	from /Users/dkinzer/.rbenv/versions/3.1.3/lib/ruby/3.1.0/open-uri.rb:31:in `open'
	from /Users/dkinzer/.rbenv/versions/3.1.3/lib/ruby/3.1.0/open-uri.rb:31:in `open'
	from (irb):9:in `<main>'
	from /Users/dkinzer/.rbenv/versions/3.1.3/lib/ruby/gems/3.1.0/gems/irb-1.4.1/exe/irb:11:in `<top (required)>'
	from /Users/dkinzer/.rbenv/versions/3.1.3/bin/irb:25:in `load'
	from /Users/dkinzer/.rbenv/versions/3.1.3/bin/irb:25:in `<top (required)>'
	from /Users/dkinzer/.rbenv/versions/3.1.3/lib/ruby/3.1.0/bundler/cli/exec.rb:58:in `load'
	from /Users/dkinzer/.rbenv/versions/3.1.3/lib/ruby/3.1.0/bundler/cli/exec.rb:58:in `kernel_load'
	from /Users/dkinzer/.rbenv/versions/3.1.3/lib/ruby/3.1.0/bundler/cli/exec.rb:23:in `run'
	from /Users/dkinzer/.rbenv/versions/3.1.3/lib/ruby/3.1.0/bundler/cli.rb:486:in `exec'
	from /Users/dkinzer/.rbenv/versions/3.1.3/lib/ruby/3.1.0/bundler/vendor/thor/lib/thor/command.rb:27:in `run'
	from /Users/dkinzer/.rbenv/versions/3.1.3/lib/ruby/3.1.0/bundler/vendor/thor/lib/thor/invocation.rb:127:in `invoke_command'
	from /Users/dkinzer/.rbenv/versions/3.1.3/lib/ruby/3.1.0/bundler/vendor/thor/lib/thor.rb:392:in `dispatch'
	from /Users/dkinzer/.rbenv/versions/3.1.3/lib/ruby/3.1.0/bundler/cli.rb:31:in `dispatch'
	from /Users/dkinzer/.rbenv/versions/3.1.3/lib/ruby/3.1.0/bundler/vendor/thor/lib/thor/base.rb:485:in `start'
	from /Users/dkinzer/.rbenv/versions/3.1.3/lib/ruby/3.1.0/bundler/cli.rb:25:in `start'
	... 5 levels...

Updated by alanwu (Alan Wu) 6 months ago

With a path, delegates to Kernel#open and in turn to
File#open, who has keyword parameters. only has rest parameters
and this mismatch along with the recent change to use super for delegation
seems to be the source of the error.

In 2.7, open-uri used a splat to delegate and it issued a deprecation message:

/opt/wandbox/ruby-2.7.3/lib/ruby/2.7.0/open-uri.rb:52: warning: Using the last argument as keyword parameters is deprecated
/opt/wandbox/ruby-2.7.3/lib/ruby/2.7.0/open-uri.rb:52:in `initialize': No such file or directory @ rb_sysopen - spec/fixtures/blogs.json (Errno::ENOENT)
	from /opt/wandbox/ruby-2.7.3/lib/ruby/2.7.0/open-uri.rb:52:in `open'
	from /opt/wandbox/ruby-2.7.3/lib/ruby/2.7.0/open-uri.rb:52:in `open'
	from prog.rb:2:in `<main>'

Maybe, **{}) is a viable workaround? Seems to work
fine for both paths and URIs on 3.1.

We can consider tweaking the delegation on the open-uri side.

Updated by jeremyevans0 (Jeremy Evans) about 1 month ago

This is a bug in It can be fixed by using ruby2_keywords. I submitted a pull request to fix it:


Also available in: Atom PDF