ferrum icon indicating copy to clipboard operation
ferrum copied to clipboard

Incompatibility with Ruby 3.4: forwardable module/configuration

Open jfi opened this issue 1 month ago • 1 comments

Describe the bug

Ferrum 0.17.1 is incompatible with Ruby 3.4 due to a breaking change in the forwardable module. The array-based delegate syntax for setter methods (ending in =) causes a SyntaxError when certain properties are set, preventing Ferrum from initializing properly.

To Reproduce

  1. Use Ruby 3.4.7 (or any Ruby 3.4.x version)
  2. Install Ferrum 0.17.1
  3. Attempt to create a Ferrum::Browser instance:
require 'ferrum'
browser = Ferrum::Browser.new(timeout: 18, process_timeout: 18)

Expected behavior

The browser should initialize successfully with the specified timeout values. Configuration options should be properly delegated to the Options object.

Actual behavior

Ruby raises a SyntaxError during delegation setup:

  Exception 'SyntaxError' at /usr/local/lib/ruby/3.4.0/forwardable/impl.rb:4
  > 0 | ().timeout=
      |           ^ expected an expression after `=`

This prevents the delegated setter methods from being created, causing:

  • Browser initialization to fail silently in some cases
  • Configuration values (like timeout and process_timeout) to be ignored
  • Fallback to default values (10 seconds) instead of configured values

Desktop (please complete the following information):

  • OS: macOS (Darwin 25.0.0), also reproduced in GitHub Actions Ubuntu runners
  • Browser: Chrome/Chromium Version 130+
  • Ferrum Version: 0.17.1
  • Ruby Version: 3.4.7 (issue affects all Ruby 3.4.x versions)

Root cause

In lib/ferrum/browser.rb at line 36:

delegate %i[timeout timeout= base_url base_url= default_user_agent default_user_agent= extensions] => :options

Ruby 3.4 changed the forwardable implementation and can no longer handle setter method names (ending in =) in the array-based delegate syntax.

Proposed fix

Replace the array-based delegation with individual def_delegator calls:

def_delegator :@options, :timeout
def_delegator :@options, :timeout=
def_delegator :@options, :base_url
def_delegator :@options, :base_url=
def_delegator :@options, :default_user_agent
def_delegator :@options, :default_user_agent=
def_delegator :@options, :extensions

Additional information

  • This issue manifests in browser automation tests where timeouts appear to be ignored
  • Error messages reference "within 10 seconds" despite configuration specifying 18 seconds
  • The SyntaxError occurs during class loading, before any browser processes are started
  • Cuprite (which depends on Ferrum) is also affected by this issue

jfi avatar Nov 23 '25 16:11 jfi

This looks like an issue in forwardable, see ruby/forwardable#35, and I've just raised this upstream at https://bugs.ruby-lang.org/issues/21708.

jfi avatar Nov 23 '25 22:11 jfi