teamcapybara/capybara · error · ArgumentError
`#within_window` requires a `Capybara::Window` instance or a
Error message
`#within_window` requires a `Capybara::Window` instance or a lambda
What it means
within_window accepts a Capybara::Window instance or a Proc/lambda used as a window locator; anything else raises ArgumentError. The common trigger is a plain String - the Capybara 1.x API allowed within_window('window_name'), which 2.x+ rejects.
Source
Thrown at lib/capybara/session.rb:555
# returns a value other than false or nil will be switched to.
# @example
# within_window(->{ page.title == 'Page title' }) { click_button 'Submit' }
# @raise [Capybara::WindowError] if no window matching lambda was found
#
# @raise [Capybara::ScopeError] if this method is invoked inside {#within_frame} method
# @return value returned by the block
#
def within_window(window_or_proc)
original = current_window
scopes << nil
begin
case window_or_proc
when Capybara::Window
_switch_to_window(window_or_proc) unless original == window_or_proc
when Proc
_switch_to_window { window_or_proc.call }
else
raise ArgumentError, '`#within_window` requires a `Capybara::Window` instance or a lambda'
end
begin
yield if block_given?
ensure
_switch_to_window(original) unless original == window_or_proc
end
ensure
scopes.pop
end
end
##
# Get the window that has been opened by the passed block.
# It will wait for it to be opened (in the same way as other Capybara methods wait).
# It's better to use this method than `windows.last`
# {https://dvcs.w3.org/hg/webdriver/raw-file/default/webdriver-spec.html#h_note_10 as order of windows isn't defined in some drivers}.
#View on GitHub (pinned to 15b5fdb76e)
Solutions
- Pass a Window object: within_window(page.windows.last) { ... }
- Or a locator lambda: within_window(-> { title == 'popup' }) { ... }
- During upgrades, grep the suite for within_window(' to catch every 1.x-style call
Example fix
# before (Capybara 1.x style)
within_window('popup') { click_link 'Close' }
# after
within_window(-> { title == 'popup' }) { click_link 'Close' }
# or
within_window(page.windows.last) { click_link 'Close' } Defensive patterns
Strategy: type-guard
Validate before calling
raise ArgumentError, 'Window or lambda required' unless window_or_proc.is_a?(Capybara::Window) || window_or_proc.is_a?(Proc)
within_window(window_or_proc) { click_link 'Close' } Type guard
def window_target?(obj) obj.is_a?(Capybara::Window) || obj.is_a?(Proc) end
Try / catch
begin
within_window(target) { yield }
rescue ArgumentError
within_window(-> { title == target }) { yield } # target was a title string
end Prevention
- Grep for string arguments to within_window when upgrading from Capybara 1.x
- Store Window objects or title-matching lambdas in page-object accessors
When it happens
Trigger: within_window('popup') { ... } left over from Capybara 1.x; passing a window handle String or a Symbol; passing page.windows.first.title as the target.
Common situations: Suite upgrades from Capybara 1.x to 2.x+; blog/docs examples predating the API change; old helpers that returned window names being passed through.
Related errors
- `switch_to_window` can take either a block or a window, not
- You must provide a frame element, :parent, or :top when call
- `switch_to_window`: either window or block should be provide
- `switch_to_window` is not supposed to be invoked from `withi
- block passed to #window_opened_by opened #{opened_handles.si
AI-assisted analysis of teamcapybara/capybara@15b5fdb76e (2026-08-21).
Data as JSON: /api/errors/639fa9fa9563fb33.
Report an issue: GitHub.