teamcapybara/capybara · error · ArgumentError

You must specify both x: and y: for a click offset

Error message

You must specify both x: and y: for a click offset

What it means

Capybara raises this ArgumentError from Element#perform_click_action when a click-type action is given an offset with only one axis. The guard `nil ^ options[:x] ^ options[:y]` is true exactly when one of x:/y: was passed and the other was omitted (or explicitly nil). Offsets are a 2D coordinate, so a partial offset is always a caller bug and is rejected before any driver call.

Source

Thrown at lib/capybara/node/element.rb:609

        base.respond_to?(:initial_cache) ? base.initial_cache : {}
      end

      STYLE_SCRIPT = <<~JS
        (function(){
          var s = window.getComputedStyle(this);
          var result = {};
          for (var i = arguments.length; i--; ) {
            var property_name = arguments[i];
            result[property_name] = s.getPropertyValue(property_name);
          }
          return result;
        }).apply(this, arguments)
      JS

    private

      def perform_click_action(keys, wait: nil, **options)
        raise ArgumentError, 'You must specify both x: and y: for a click offset' if nil ^ options[:x] ^ options[:y]

        options[:offset] ||= :center if session_options.w3c_click_offset
        synchronize(wait) { yield keys, options }
        self
      end
    end
  end
end

View on GitHub (pinned to 15b5fdb76e)

Solutions

  1. Pass both coordinates: click(x: 10, y: 20), or pass neither for a centered click
  2. If one axis should default (e.g. y centered), supply a concrete default yourself: click(x: offset_x, y: 0)
  3. Check interpolated offset variables for nil before calling click when offsets come from computation

Example fix

# before
el.click(x: 50)

# after
el.click(x: 50, y: 10)
# or centered click with no offset at all
el.click
Defensive patterns

Strategy: validation

Validate before calling

def safe_click(el, x: nil, y: nil, **opts)
  raise ArgumentError, 'click offset needs both x and y' if x.nil? != y.nil?
  x.nil? ? el.click(**opts) : el.click(x: x, y: y, **opts)
end

Type guard

def valid_click_offset?(opts)
  opts.key?(:x) == opts.key?(:y)
end

Try / catch

begin
  el.click(x: 10, y: 20)
rescue ArgumentError => e
  raise unless e.message.include?('x: and y:')
  el.click # fall back to centered click only if that is acceptable
end

Prevention

When it happens

Trigger: Calling element.click(x: 10) without y:, or click(y: 5) without x:, or explicitly passing click(x: nil, y: 20). The same perform_click_action path serves click, double_click, right_click, click_at-style helpers and double_tap/two_finger_tap on touch drivers, so any of those with a half-specified offset raises immediately.

Common situations: Developer copies an example that scrolls-and-clicks by horizontal offset only; dynamic offset code computes x from one variable and y from another and one evaluates to nil; wrapping click in a helper that forwards **options where the caller only set one key.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of teamcapybara/capybara@15b5fdb76e (2026-08-21). Data as JSON: /api/errors/268303e8ef2d598c. Report an issue: GitHub.