open-uri icon indicating copy to clipboard operation
open-uri copied to clipboard

Incorrect API for `IO#read`: 2 parameters expected, only 1 accepted

Open francois opened this issue 5 months ago • 1 comments

Ruby's IO#read declares 2 parameters: def read(maxlen = nil, out_string = nil).

OpenURI::OpenRead declares a single Hash parameter: https://github.com/ruby/open-uri/blob/0523bdb6b2bf2931bb4774718ada4da3ce7617b5/lib/open-uri.rb#L812

Marcel, a mime-type detection library, expects to use the 2 parameter form of IO#read: https://github.com/rails/marcel/blob/170458c687ed22f07d8829043a04e008a2b1936b/lib/marcel/magic.rb#L136

This inconsistency results in a crash like this:

/Users/francois/.rvm/gems/ruby-3.4.4/gems/open-uri-0.3.0/lib/open-uri.rb:747:in 'read': wrong number of arguments (given 2, expected 0..1) (ArgumentError)
        from /Users/francois/.rvm/gems/ruby-3.4.4/gems/marcel-1.0.4/lib/marcel/magic.rb:136:in 'block in Marcel::Magic.magic_match_io'
        from /Users/francois/.rvm/gems/ruby-3.4.4/gems/marcel-1.0.4/lib/marcel/magic.rb:128:in 'Array#any?'
        from /Users/francois/.rvm/gems/ruby-3.4.4/gems/marcel-1.0.4/lib/marcel/magic.rb:128:in 'Marcel::Magic.magic_match_io'
        from /Users/francois/.rvm/gems/ruby-3.4.4/gems/marcel-1.0.4/lib/marcel/magic.rb:124:in 'block in Marcel::Magic.magic_match'
        from /Users/francois/.rvm/gems/ruby-3.4.4/gems/marcel-1.0.4/lib/marcel/magic.rb:124:in 'Array#each'
        from /Users/francois/.rvm/gems/ruby-3.4.4/gems/marcel-1.0.4/lib/marcel/magic.rb:124:in 'Enumerable#find'
        from /Users/francois/.rvm/gems/ruby-3.4.4/gems/marcel-1.0.4/lib/marcel/magic.rb:124:in 'Marcel::Magic.magic_match'
        from /Users/francois/.rvm/gems/ruby-3.4.4/gems/marcel-1.0.4/lib/marcel/magic.rb:87:in 'Marcel::Magic.by_magic'
        from /Users/francois/.rvm/gems/ruby-3.4.4/gems/marcel-1.0.4/lib/marcel/mime_type.rb:39:in 'block in Marcel::MimeType.for_data'
        from /Users/francois/.rvm/gems/ruby-3.4.4/gems/marcel-1.0.4/lib/marcel/mime_type.rb:75:in 'Marcel::MimeType.with_io'
        from /Users/francois/.rvm/gems/ruby-3.4.4/gems/marcel-1.0.4/lib/marcel/mime_type.rb:38:in 'Marcel::MimeType.for_data'
        from /Users/francois/.rvm/gems/ruby-3.4.4/gems/marcel-1.0.4/lib/marcel/mime_type.rb:31:in 'Marcel::MimeType.for'
        from /Users/francois/.rvm/gems/ruby-3.4.4/gems/ruby_llm-1.3.1/lib/ruby_llm/mime_type.rb:11:in 'RubyLLM::MimeType.for'
        from /Users/francois/.rvm/gems/ruby-3.4.4/gems/ruby_llm-1.3.1/lib/ruby_llm/attachment.rb:102:in 'RubyLLM::Attachment#determine_mime_type'
        from /Users/francois/.rvm/gems/ruby-3.4.4/gems/ruby_llm-1.3.1/lib/ruby_llm/attachment.rb:22:in 'RubyLLM::Attachment#initialize'
        from /Users/francois/.rvm/gems/ruby-3.4.4/gems/ruby_llm-1.3.1/lib/ruby_llm/content.rb:18:in 'Class#new'
        from /Users/francois/.rvm/gems/ruby-3.4.4/gems/ruby_llm-1.3.1/lib/ruby_llm/content.rb:18:in 'RubyLLM::Content#add_attachment'
        from /Users/francois/.rvm/gems/ruby-3.4.4/gems/ruby_llm-1.3.1/lib/ruby_llm/content.rb:39:in 'block in RubyLLM::Content#process_attachments_array_or_string'
        from /Users/francois/.rvm/gems/ruby-3.4.4/gems/ruby_llm-1.3.1/lib/ruby_llm/content.rb:38:in 'Array#each'
        from /Users/francois/.rvm/gems/ruby-3.4.4/gems/ruby_llm-1.3.1/lib/ruby_llm/content.rb:38:in 'RubyLLM::Content#process_attachments_array_or_string'
        from /Users/francois/.rvm/gems/ruby-3.4.4/gems/ruby_llm-1.3.1/lib/ruby_llm/content.rb:48:in 'RubyLLM::Content#process_attachments'
        from /Users/francois/.rvm/gems/ruby-3.4.4/gems/ruby_llm-1.3.1/lib/ruby_llm/content.rb:13:in 'RubyLLM::Content#initialize'
        from /Users/francois/.rvm/gems/ruby-3.4.4/gems/ruby_llm-1.3.1/lib/ruby_llm/chat.rb:35:in 'Class#new'
        from /Users/francois/.rvm/gems/ruby-3.4.4/gems/ruby_llm-1.3.1/lib/ruby_llm/chat.rb:35:in 'RubyLLM::Chat#ask'
        from /Users/francois/Projects/marketplace/a.rb:13:in '<main>'
...
$ ruby --version
ruby 3.4.4 (2025-05-14 revision a38531fd3f) +PRISM [arm64-darwin24]
$ bundle show open-uri
/Users/francois/.rvm/gems/ruby-3.4.4/gems/open-uri-0.3.0
$ bundle show marcel
/Users/francois/.rvm/gems/ruby-3.4.4/gems/marcel-1.0.4
$ bundle show rails
/Users/francois/.rvm/gems/ruby-3.4.4/gems/rails-7.2.2.1

I tried using OpenURI 0.5.0, with essentially the same backtrace:

/Users/francois/.rvm/gems/ruby-3.4.4/gems/open-uri-0.5.0/lib/open-uri.rb:812:in 'read': wrong number of arguments (given 2, expected 0..1) (ArgumentError)
        from /Users/francois/.rvm/gems/ruby-3.4.4/gems/marcel-1.0.4/lib/marcel/magic.rb:136:in 'block in Marcel::Magic.magic_match_io'
        from /Users/francois/.rvm/gems/ruby-3.4.4/gems/marcel-1.0.4/lib/marcel/magic.rb:128:in 'Array#any?'
        from /Users/francois/.rvm/gems/ruby-3.4.4/gems/marcel-1.0.4/lib/marcel/magic.rb:128:in 'Marcel::Magic.magic_match_io'
        from /Users/francois/.rvm/gems/ruby-3.4.4/gems/marcel-1.0.4/lib/marcel/magic.rb:124:in 'block in Marcel::Magic.magic_match'
        from /Users/francois/.rvm/gems/ruby-3.4.4/gems/marcel-1.0.4/lib/marcel/magic.rb:124:in 'Array#each'
        from /Users/francois/.rvm/gems/ruby-3.4.4/gems/marcel-1.0.4/lib/marcel/magic.rb:124:in 'Enumerable#find'
        from /Users/francois/.rvm/gems/ruby-3.4.4/gems/marcel-1.0.4/lib/marcel/magic.rb:124:in 'Marcel::Magic.magic_match'

If I start a new project and leave out open-uri from the Gemfile (meaning I get the default version bundled with Ruby 3.4.4), Marcel does not raise an error.

francois avatar Jul 17 '25 19:07 francois

@jeremy from rails/marcel, does this ring a bell? Not sure if this is an error in OpenURI or Marcel.

francois avatar Jul 17 '25 19:07 francois