{"record":{"id":"4ba8a199adc8e96d","repo":"teamcapybara/capybara","slug":"switch-to-window-is-not-supposed-to-be-invoked-f","errorCode":null,"errorMessage":"`switch_to_window` is not supposed to be invoked from `within` or `within_frame` blocks.","messagePattern":"`switch_to_window` is not supposed to be invoked from `within` or `within_frame` blocks\\.","errorType":"exception","errorClass":"Capybara::ScopeError","httpStatus":null,"severity":"error","filePath":"lib/capybara/session.rb","lineNumber":517,"sourceCode":"    #   If window that matches block can't be found, the window will be switched back and {Capybara::WindowError} will be raised.\n    #   @example\n    #     window = switch_to_window { title == 'Page title' }\n    #   @raise [Capybara::WindowError]     if no window matches given block\n    # @overload switch_to_window(window)\n    #   @param window [Capybara::Window]   window that should be switched to\n    #   @raise [Capybara::Driver::Base#no_such_window_error] if nonexistent (e.g. closed) window was passed\n    #\n    # @return [Capybara::Window]         window that has been switched to\n    # @raise [Capybara::ScopeError]        if this method is invoked inside {#within} or\n    #   {#within_frame} methods\n    # @raise [ArgumentError]               if both or neither arguments were provided\n    #\n    def switch_to_window(window = nil, **options, &window_locator)\n      raise ArgumentError, '`switch_to_window` can take either a block or a window, not both' if window && window_locator\n      raise ArgumentError, '`switch_to_window`: either window or block should be provided' if !window && !window_locator\n\n      unless scopes.last.nil?\n        raise Capybara::ScopeError, '`switch_to_window` is not supposed to be invoked from ' \\\n                                    '`within` or `within_frame` blocks.'\n      end\n\n      _switch_to_window(window, **options, &window_locator)\n    end\n\n    ##\n    # This method does the following:\n    #\n    # 1. Switches to the given window (it can be located by window instance/lambda/string).\n    # 2. Executes the given block (within window located at previous step).\n    # 3. Switches back (this step will be invoked even if an exception occurs at the second step).\n    #\n    # @overload within_window(window) { do_something }\n    #   @param window [Capybara::Window]       instance of {Capybara::Window} class\n    #     that will be switched to\n    #   @raise [driver#no_such_window_error] if nonexistent (e.g. closed) window was passed\n    # @overload within_window(proc_or_lambda) { do_something }","sourceCodeStart":499,"sourceCodeEnd":535,"githubUrl":"https://github.com/teamcapybara/capybara/blob/15b5fdb76e972e9623d5af2123ed3755594f9732/lib/capybara/session.rb#L499-L535","documentation":"switch_to_window permanently changes which window subsequent finders query, so Capybara forbids it while a within or within_frame scope is active (scopes.last non-nil) and raises Capybara::ScopeError naming those blocks as the cause.","triggerScenarios":"within('.modal') { switch_to_window(chat_window) }; within_frame { switch_to_window { title == 'Chat' } }; page-object methods called from inside a scoped block that switch windows.","commonSituations":"Popups triggered from scoped sections (clicking a button within a modal opens a new window); feature flows mixing within with window management; helpers that switch windows reused from scoped contexts.","solutions":["Move the switch outside the within block, then re-scope: switch_to_window(w); within('.modal') { ... }","Use within_window(w) { ... } for temporary window scoping - it restores the original window on exit","Restructure page objects so window switches happen at top level, never inside scoped helpers"],"exampleFix":"# before\nwithin('.modal') do\n  switch_to_window(chat_window) # Capybara::ScopeError\nend\n\n# after\nswitch_to_window(chat_window)\nwithin('.modal') { click_button 'Send' }","handlingStrategy":"validation","validationCode":"switch_to_window(chat_window) if page.send(:scopes).last.nil?","typeGuard":null,"tryCatchPattern":"begin\n  switch_to_window(w)\nrescue Capybara::ScopeError\n  within_window(w) { yield } # temporary scope instead of a permanent switch\nend","preventionTips":["Use within_window for scoped cross-window work","Keep window switching at the top level of specs and page objects"],"tags":["windows","scope","within","switch-to-window"],"backgroundTag":"window-scope-violation","analyzedSha":"15b5fdb76e972e9623d5af2123ed3755594f9732","analyzedAt":"2026-08-21T16:53:45.588Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}