Skip to content

Allow user-provided OAuth URL for LLM discovery

c2801af
Select commit
Loading
Failed to load commit list.
Sign in for the full log view
Open

MCP Server Part 10: OAuth discovery #3767

Allow user-provided OAuth URL for LLM discovery
c2801af
Select commit
Loading
Failed to load commit list.
GitHub Actions / Test Results Summary succeeded May 13, 2026 in 1s

731 passed, 2 failed and 10 skipped

Tests failed

Report Passed Failed Skipped Time
test-results/test-main-results-py3.12-group1/junit_intg.xml 158✅ 3⚪ 339s
test-results/test-main-results-py3.12-group2/junit_intg.xml 130✅ 1❌ 1⚪ 465s
test-results/test-main-results-py3.12-group3/junit_intg.xml 106✅ 1⚪ 295s
test-results/test-main-results-py3.8-group1/junit_intg.xml 131✅ 1❌ 2⚪ 265s
test-results/test-main-results-py3.8-group2/junit_intg.xml 110✅ 2⚪ 417s
test-results/test-main-results-py3.8-group3/junit_intg.xml 96✅ 1⚪ 239s

✅ test-results/test-main-results-py3.12-group1/junit_intg.xml

161 tests were completed in 339s with 158 passed, 0 failed and 3 skipped.

❌ test-results/test-main-results-py3.12-group2/junit_intg.xml

132 tests were completed in 465s with 130 passed, 1 failed and 1 skipped.

Test suite Passed Failed Skipped Time
pytest 130✅ 1❌ 1⚪ 465s

❌ pytest

tests.integration.devtools.test_callback_validation
  ✅ test_dvcv002_blank_id_prop
  ✅ test_dvcv003_duplicate_outputs_same_callback
  ✅ test_dvcv004_duplicate_outputs_across_callbacks
  ✅ test_dvcv005_input_output_overlap
  ✅ test_dvcv006_inconsistent_wildcards
  ✅ test_dvcv007_disallowed_ids
  ✅ test_dvcv008_wrong_callback_id
  ✅ test_dvcv009_suppress_callback_exceptions
  ✅ test_dvcv010_bad_props
  ✅ test_dvcv011_duplicate_outputs_simple
  ✅ test_dvcv012_circular_2_step
  ✅ test_dvcv013_circular_3_step
  ✅ test_dvcv014_multipage_errors
  ✅ test_dvcv015_multipage_validation_layout[function]
  ✅ test_dvcv015_multipage_validation_layout[attribute]
  ✅ test_dvcv015_multipage_validation_layout[suppress]
  ✅ test_dvcv016_circular_with_input_output
  ✅ test_dvcv017_match_input_permitted_no_output_match
tests.integration.devtools.test_devtools_error_handling
  ✅ test_dveh001_python_errors
  ✅ test_dveh006_long_python_errors
  ✅ test_dveh002_prevent_update_not_in_error_msg
  ✅ test_dveh003_validation_errors_in_place
  ✅ test_dveh004_validation_errors_creation
  ✅ test_dveh005_multiple_outputs
tests.integration.devtools.test_devtools_ui
  ✅ test_dvui001_disable_props_check_config
  ✅ test_dvui002_disable_ui_config
  ✅ test_dvui003_callback_graph
  ✅ test_dvui004_width_props
  ✅ test_dvui005_undo_redo
  ✅ test_dvui006_no_undo_redo
  ✅ test_dvui007_other_before_request_func
tests.integration.devtools.test_hot_reload
  ✅ test_dvhr001_hot_reload
tests.integration.devtools.test_props_check
  ⚪ test_dvpc001_prop_check_errors_with_path
tests.integration.mcp.primitives.tools.test_tool_decorated_mcp_functions
  ✅ test_mcpd001_bare_decorator_appears_as_tool
  ✅ test_mcpd002_expose_docstring
  ✅ test_mcpd003_custom_name_overrides_function_name
  ✅ test_mcpd004_typed_params_produce_schema
  ✅ test_mcpd005_optional_param_not_required
  ✅ test_mcpd006_return_annotation_becomes_output_schema
  ✅ test_mcpd007_call_returns_result
  ✅ test_mcpd008_call_with_custom_name
  ✅ test_mcpd009_call_error_returns_is_error
tests.integration.mcp.test_mcp_background_tasks
  ✅ test_mcpbg012_trigger_poll_and_retrieve
  ✅ test_mcpbg013_result_expires
  ✅ test_mcpbg014_progress_in_poll_response
  ✅ test_mcpbg015_background_tools_in_tools_list
  ❌ test_mcpbg016_per_callback_manager_lookup
	def test_mcpbg016_per_callback_manager_lookup():
tests.integration.mcp.test_mcp_callback_behavior
  ✅ test_mcpb001_positional_callback
  ✅ test_mcpb002_positional_with_state
  ✅ test_mcpb003_multi_output_positional
  ✅ test_mcpb004_dict_based_inputs_and_state
  ✅ test_mcpb005_dict_based_outputs
  ✅ test_mcpb006_mixed_input_state_in_inputs
  ✅ test_mcpb007_tuple_grouped_inputs
  ✅ test_mcpb008_initial_values_from_chained_callbacks
  ✅ test_mcpb009_dict_based_reordered_state_input
  ✅ test_mcpb010_pattern_matching_callback
  ✅ test_mcpb011_pattern_matching_with_all_wildcard
  ✅ test_mcpb012_pattern_matching_mixed_outputs
  ✅ test_mcpb013_pattern_matching_with_match_wildcard
  ✅ test_mcpb014_pattern_matching_with_allsmaller_wildcard
  ✅ test_mcpb015_prevent_initial_call_uses_layout_default
  ✅ test_mcpb016_initial_callback_overrides_layout_value
  ✅ test_mcpb017_callback_context_triggered_id
  ✅ test_mcpb018_no_output_callback_does_not_crash_tools_list
  ✅ test_mcpb019_duplicate_outputs_both_tools_listed
  ✅ test_mcpb020_duplicate_outputs_both_callable
  ✅ test_mcpb021_duplicate_outputs_find_by_output_returns_primary
  ✅ test_mcpb022_tool_names_within_64_chars
  ✅ test_mcpb023_long_callback_ids_within_64_chars
  ✅ test_mcpb024_pattern_matching_ids_within_64_chars
  ✅ test_mcpb025_duplicate_func_names_produce_unique_tools
  ✅ test_mcpb026_builtin_tools_always_present
  ✅ test_mcpb027_mcp_tool_with_label_and_date_picker_schema
  ✅ test_mcpb028_query_component_returns_structured_output
tests.integration.mcp.test_mcp_endpoint
  ✅ test_mcpe001_post_initialize_returns_protocol_version
  ✅ test_mcpe002_post_tools_list
  ✅ test_mcpe003_notification_returns_202
  ✅ test_mcpe004_delete_returns_405
  ✅ test_mcpe005_get_returns_405
  ✅ test_mcpe006_post_rejects_wrong_content_type
  ✅ test_mcpe007_routes_not_registered_when_disabled
  ✅ test_mcpe008_routes_respect_pathname_prefix
  ✅ test_mcpe009_enable_mcp_env_var_false
  ✅ test_mcpe010_constructor_overrides_env_var
tests.integration.mcp.test_mcp_resources
  ✅ test_mcpz001_resources_list_includes_layout
  ✅ test_mcpz002_read_layout_resource
tests.integration.mcp.test_mcp_session
  ✅ test_mcpse_e2e001_full_session_lifecycle
  ✅ test_mcpse_e2e002_stale_session_recovers_with_notifications
  ✅ test_mcpse_e2e003_capabilities_advertise_list_changed
tests.integration.multi_page.test_pages_layout
  ✅ test_pala001_layout
  ✅ test_pala002_meta_tags_default
  ✅ test_pala003_meta_tags_custom
  ✅ test_pala004_no_layout_exception
  ✅ test_pala005_routing_inputs
  ✅ test_pala006_pages_external_library
  ✅ test_pala007_app_title_discription
tests.integration.multi_page.test_pages_order
  ✅ test_paor001_order
tests.integration.multi_page.test_pages_relative_path
  ✅ test_pare001_relative_path
  ✅ test_pare002_relative_path_with_url_base_pathname
  ✅ test_pare003_absolute_path
tests.integration.renderer.test_add_receive_props
  ✅ test_rdarp001_add_receive_props
tests.integration.renderer.test_array_of_exact_or_shape_with_node_prop_assign_none
  ✅ test_aoeoswnpsn001_array_of_exact_or_shape_with_node_prop_assign_none
tests.integration.renderer.test_benchmarking
  ✅ test_compute_graph_timing[dev_tools0-disabled]
  ✅ test_compute_graph_timing[dev_tools1-enabled]
tests.integration.renderer.test_children_reorder
  ✅ test_roc001_reorder_children
tests.integration.renderer.test_component_as_prop
  ✅ test_rdcap001_component_as_prop
  ✅ test_rdcap002_component_as_props_dynamic_id
  ✅ test_rdcap003_side_effect_regression
  ✅ test_rdcap004_side_effect_same_component
tests.integration.renderer.test_dependencies
  ✅ test_rddp001_dependencies_on_components_that_dont_exist
tests.integration.renderer.test_descendant_listening
  ✅ test_dcl001_descendant_tabs
tests.integration.renderer.test_due_diligence
  ✅ test_rddd001_initial_state
  ✅ test_rddd002_falsy_child[0]
  ✅ test_rddd002_falsy_child[child1]
tests.integration.renderer.test_external_component
  ✅ test_rext001_render_external_component
  ✅ test_rext002_render_external_component_temp
tests.integration.renderer.test_iframe
  ✅ test_rdif001_sandbox_allow_scripts
tests.integration.renderer.test_loading_states
  ✅ test_rdls001_multi_loading_components
  ✅ test_rdls002_chained_loading_states
  ✅ test_rdls003_update_title[kwargs0-Updating...-False]
  ✅ test_rdls003_update_title[kwargs1-Dash-False]
  ✅ test_rdls003_update_title[kwargs2-Dash-False]
  ✅ test_rdls003_update_title[kwargs3-Hello World-False]
  ✅ test_rdls003_update_title[kwargs4-Updating...-True]
  ✅ test_rdls003_update_title[kwargs5-Dash-True]
  ✅ test_rdls003_update_title[kwargs6-Dash-True]
  ✅ test_rdls003_update_title[kwargs7-Hello World-True]
  ✅ test_rdls004_update_title_chained_callbacks[None]
  ✅ test_rdls004_update_title_chained_callbacks[Custom Update Title]
  ✅ test_rdls005_persistent_callback_no_update_title
tests.integration.renderer.test_multi_output
  ✅ test_rdmo001_single_input_multi_outputs_on_multiple_components

✅ test-results/test-main-results-py3.12-group3/junit_intg.xml

107 tests were completed in 295s with 106 passed, 0 failed and 1 skipped.

❌ test-results/test-main-results-py3.8-group1/junit_intg.xml

134 tests were completed in 265s with 131 passed, 1 failed and 2 skipped.

Test suite Passed Failed Skipped Time
pytest 131✅ 1❌ 2⚪ 265s

❌ pytest

tests.integration.callbacks.test_api_callback
  ✅ test_apib001_api_callback
tests.integration.callbacks.test_arbitrary_callbacks
  ✅ test_arb001_global_set_props
  ✅ test_arb002_no_output_callbacks
  ✅ test_arb003_arbitrary_pages
  ✅ test_arb004_wildcard_set_props
  ✅ test_arb005_no_output_error
  ✅ test_arb006_multi_set_props
  ✅ test_arb007_clientside_no_output
  ❌ test_arb008_set_props_chain_cb
	dash_duo = <dash.testing.composite.DashComposite object at 0x7f83026c53a0>
tests.integration.callbacks.test_basic_callback
  ✅ test_cbsc001_simple_callback
  ✅ test_cbsc002_callbacks_generating_children
  ✅ test_cbsc003_callback_with_unloaded_async_component
  ✅ test_cbsc004_callback_using_unloaded_async_component
  ✅ test_cbsc005_children_types[json]
  ✅ test_cbsc005_children_types[orjson]
  ✅ test_cbsc006_array_of_objects[json]
  ✅ test_cbsc006_array_of_objects[orjson]
  ✅ test_cbsc007_parallel_updates[False]
  ✅ test_cbsc007_parallel_updates[True]
  ✅ test_cbsc008_wildcard_prop_callbacks
  ✅ test_cbsc009_callback_using_unloaded_async_component_and_graph
  ✅ test_cbsc010_event_properties
  ✅ test_cbsc011_one_call_for_multiple_outputs_initial
  ✅ test_cbsc012_one_call_for_multiple_outputs_update
  ✅ test_cbsc013_multi_output_out_of_order
  ✅ test_cbsc014_multiple_properties_update_at_same_time_on_same_component
  ✅ test_cbsc015_input_output_callback
  ✅ test_cbsc016_extra_components_callback
  ✅ test_cbsc017_callback_directly_callable
  ✅ test_cbsc018_callback_ndarray_output
  ✅ test_cbsc019_callback_running
  ✅ test_cbsc020_callback_running_non_existing_component
  ✅ test_cbsc021_callback_running_non_existing_component
  ✅ test_cbsc022_no_output_callback_initial_call
  ✅ test_cbsc023_no_input_callback_initial_call
  ✅ test_cbsc024_no_input_no_output_callback_initial_call
  ✅ test_cbsc025_multiple_no_input_no_output_callbacks
  ✅ test_cbsc026_no_input_with_duplicate_outputs
tests.integration.callbacks.test_callback_context
  ✅ test_cbcx001_modified_response
  ✅ test_cbcx002_triggered
  ⚪ test_cbcx003_no_callback_context
  ✅ test_cbcx004_triggered_backward_compat
  ⚪ test_cbcx005_grouped_clicks
  ✅ test_cbcx006_initial_callback_predecessor
  ✅ test_cbcx007_triggered_id
  ✅ test_cbcx008_triggered_id_pmc
tests.integration.callbacks.test_callback_error
  ✅ test_cber001_error_handler
tests.integration.callbacks.test_callback_optional
  ✅ test_cbop001_optional_input
  ✅ test_cbop002_optional_state
tests.integration.callbacks.test_dynamic_callback
  ✅ test_dync001_dynamic_callback
  ✅ test_dync002_dynamic_callback_without_element
  ✅ test_dyn003_dynamic_callback_import_library
tests.integration.callbacks.test_global_dash_callback
  ✅ test_dash_callback_001
tests.integration.callbacks.test_layout_paths_with_callbacks
  ✅ test_cblp001_radio_buttons_callbacks_generating_children
tests.integration.callbacks.test_malformed_request
  ✅ test_cbmf001_bad_output_outputs
tests.integration.callbacks.test_missing_inputs
  ✅ test_cbmi001_all_missing_inputs
  ✅ test_cbmi002_follow_on_to_two_skipped_callbacks
  ✅ test_cbmi003_some_missing_inputs
  ✅ test_cbmi004_some_missing_outputs
  ✅ test_cbmi005_all_multi_wildcards_with_output
  ✅ test_cbmi006_all_multi_wildcards_no_outputs
  ✅ test_cbmi007_all_multi_wildcards_some_outputs
  ✅ test_cbmi008_multi_wildcards_and_simple_all_missing
  ✅ test_cbmi009_match_wildcards_all_missing
tests.integration.callbacks.test_missing_outputs
  ✅ test_cbmo001_all_output[False]
  ✅ test_cbmo001_all_output[True]
  ✅ test_cbmo002_all_and_match_output[False]
  ✅ test_cbmo002_all_and_match_output[True]
  ✅ test_cbmo003_multi_all
  ✅ test_cbmo004_removing_element_while_waiting_to_update
  ✅ test_cbmo005_no_update_single_to_multi
tests.integration.callbacks.test_multiple_callbacks
  ✅ test_cbmt001_called_multiple_times_and_out_of_order
  ✅ test_cbmt002_canceled_intermediate_callback
  ✅ test_cbmt003_chain_with_table
  ✅ test_cbmt004_chain_with_sliders[False]
  ✅ test_cbmt004_chain_with_sliders[True]
  ✅ test_cbmt005_multi_converging_chain
  ✅ test_cbmt006_derived_props
  ✅ test_cbmt007_early_preventupdate_inputs_above_below
  ✅ test_cbmt008_direct_chain
  ✅ test_cbmt009_branched_chain
  ✅ test_cbmt010_shared_grandparent
  ✅ test_cbmt011_callbacks_triggered_on_generated_output
  ✅ test_cbmt012_initialization_with_overlapping_outputs[False]
  ✅ test_cbmt012_initialization_with_overlapping_outputs[True]
  ✅ test_cbmt013_chained_callback_should_be_blocked
tests.integration.callbacks.test_prevent_initial
  ✅ test_cbpi001_prevent_initial_call[flavor0]
  ✅ test_cbpi001_prevent_initial_call[flavor1]
  ✅ test_cbpi001_prevent_initial_call[flavor2]
  ✅ test_cbpi001_prevent_initial_call[flavor3]
  ✅ test_cbpi001_prevent_initial_call[flavor4]
  ✅ test_cbpi002_pattern_matching[flavor0]
  ✅ test_cbpi002_pattern_matching[flavor1]
  ✅ test_cbpi002_pattern_matching[flavor2]
  ✅ test_cbpi002_pattern_matching[flavor3]
  ✅ test_cbpi002_pattern_matching[flavor4]
  ✅ test_cbpi003_multi_outputs[flavor0]
  ✅ test_cbpi003_multi_outputs[flavor1]
  ✅ test_cbpi003_multi_outputs[flavor2]
  ✅ test_cbpi003_multi_outputs[flavor3]
  ✅ test_cbpi003_multi_outputs[flavor4]
  ✅ test_cbpi004_positional_arg
tests.integration.callbacks.test_prevent_update
  ✅ test_cbpu001_aborted_callback
  ✅ test_cbpu002_multi_output_no_update
  ✅ test_cbpu003_no_update_chains
tests.integration.callbacks.test_validation
  ✅ test_cbva001_callback_dep_types
  ✅ test_cbva002_callback_return_validation
  ✅ test_cbva003_list_single_output
  ✅ test_cbva004_named_args[True-True-True]
  ✅ test_cbva004_named_args[True-True-False]
  ✅ test_cbva004_named_args[False-False-True]
  ✅ test_cbva004_named_args[False-False-False]
  ✅ test_cbva005_tuple_args
tests.integration.callbacks.test_wildcards
  ✅ test_cbwc001_todo_app[False]
  ✅ test_cbwc001_todo_app[True]
  ✅ test_cbwc002_fibonacci_app[False]
  ✅ test_cbwc002_fibonacci_app[True]
  ✅ test_cbwc003_same_keys
  ✅ test_cbwc004_layout_chunk_changed_props
  ✅ test_cbwc005_callbacks_count
  ✅ test_cbwc006_grouping_callbacks
  ✅ test_cbwc007_pmc_update_subtree_ordering
  ✅ test_cbwc008_running_match
  ✅ test_cbwc009_match_input_fixed_output
  ✅ test_cbwc010_match_input_no_output
tests.integration.clientside.test_clientside
  ✅ test_clsd001_simple_clientside_serverside_callback
  ✅ test_clsd002_chained_serverside_clientside_callbacks
  ✅ test_clsd003_clientside_exceptions_halt_subsequent_updates
  ✅ test_clsd004_clientside_multiple_outputs
  ✅ test_clsd006_PreventUpdate
  ✅ test_clsd007_no_update
  ✅ test_clsd008_clientside_inline_source
  ✅ test_clsd009_clientside_callback_context_triggered
  ✅ test_clsd010_clientside_callback_context_inputs

✅ test-results/test-main-results-py3.8-group2/junit_intg.xml

112 tests were completed in 417s with 110 passed, 0 failed and 2 skipped.

✅ test-results/test-main-results-py3.8-group3/junit_intg.xml

97 tests were completed in 239s with 96 passed, 0 failed and 1 skipped.

Annotations

Check failure on line 0 in test-results/test-main-results-py3.12-group2/junit_intg.xml

See this annotation in the file changed.

@github-actions github-actions / Test Results Summary

pytest ► tests.integration.mcp.test_mcp_background_tasks ► test_mcpbg016_per_callback_manager_lookup

Failed test found in:
  test-results/test-main-results-py3.12-group2/junit_intg.xml
Error:
  def test_mcpbg016_per_callback_manager_lookup():
Raw output
def test_mcpbg016_per_callback_manager_lookup():
        """``tasks/get`` uses the manager attached to the specific callback."""
        manager_a = DiskcacheManager(diskcache.Cache())
        manager_b = DiskcacheManager(diskcache.Cache())
    
        app = Dash(__name__)
        app.layout = html.Div(
            [
                html.Div(id="input_a"),
                html.Div(id="output_a"),
                html.Div(id="input_b"),
                html.Div(id="output_b"),
            ]
        )
    
        @app.callback(
            Output("output_a", "children"),
            Input("input_a", "children"),
            background=True,
            manager=manager_a,
        )
        def callback_a(value):
            time.sleep(0.5)
            return f"a: {value}"
    
        @app.callback(
            Output("output_b", "children"),
            Input("input_b", "children"),
            background=True,
            manager=manager_b,
        )
        def callback_b(value):
            time.sleep(0.5)
            return f"b: {value}"
    
        client = app.server.test_client()
    
        r = _post(
            client,
            "tools/call",
            {"name": "callback_b", "arguments": {"value": "hello"}},
        )
        assert r.status_code == 200
        task_info = json.loads(json.loads(r.data)["result"]["content"][0]["text"])
        task_id = task_info["taskId"]
        cache_key = task_id.split(":")[2]
    
        deadline = time.time() + 5
        while time.time() < deadline:
            if manager_b.result_ready(cache_key):
                break
            time.sleep(0.1)
    
        assert manager_b.result_ready(cache_key)
        assert not manager_a.result_ready(cache_key)
    
        r = _post(client, "tasks/get", {"taskId": task_id}, request_id=2)
        assert r.status_code == 200
>       assert json.loads(r.data)["result"]["status"] == "completed"
E       AssertionError: assert 'working' == 'completed'
E         
E         - completed
E         + working

tests/integration/mcp/test_mcp_background_tasks.py:326: AssertionError

Check failure on line 0 in test-results/test-main-results-py3.8-group1/junit_intg.xml

See this annotation in the file changed.

@github-actions github-actions / Test Results Summary

pytest ► tests.integration.callbacks.test_arbitrary_callbacks ► test_arb008_set_props_chain_cb

Failed test found in:
  test-results/test-main-results-py3.8-group1/junit_intg.xml
Error:
  dash_duo = <dash.testing.composite.DashComposite object at 0x7f83026c53a0>
Raw output
dash_duo = <dash.testing.composite.DashComposite object at 0x7f83026c53a0>

    def test_arb008_set_props_chain_cb(dash_duo):
        app = Dash(suppress_callback_exceptions=True)
    
        app.layout = html.Div(
            [
                html.Button("origin button", id="origin-button"),
                html.Div(id="generated-button-container"),
                html.Div("initial text", id="generated-button-output"),
            ],
            style={"padding": 50},
        )
    
        @app.callback(
            Input("origin-button", "n_clicks"),
        )
        def generate_button(n_clicks):
            set_props(
                "generated-button-container",
                {
                    "children": html.Button(
                        "generated button", id="generated-button", n_clicks=0
                    )
                },
            )
    
        @app.callback(
            Output("generated-button-output", "children"),
            Input("generated-button", "n_clicks", allow_optional=True),
            prevent_initial_call=True,
        )
        def update_output(n_clicks):
            return f"n_clicks: {n_clicks}"
    
        dash_duo.start_server(app)
    
        dash_duo.wait_for_element("#origin-button").click()
        for i in range(1, 5):
>           dash_duo.wait_for_element("#generated-button").click()

tests/integration/callbacks/test_arbitrary_callbacks.py:274: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
/opt/hostedtoolcache/Python/3.8.18/x64/lib/python3.8/site-packages/selenium/webdriver/remote/webelement.py:89: in click
    self._execute(Command.CLICK_ELEMENT)
/opt/hostedtoolcache/Python/3.8.18/x64/lib/python3.8/site-packages/selenium/webdriver/remote/webelement.py:773: in _execute
    return self._parent.execute(command, params)
/opt/hostedtoolcache/Python/3.8.18/x64/lib/python3.8/site-packages/selenium/webdriver/remote/webdriver.py:430: in execute
    self.error_handler.check_response(response)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <selenium.webdriver.remote.errorhandler.ErrorHandler object at 0x7f83026c5610>
response = {'status': 404, 'value': '{"value":{"error":"stale element reference","message":"stale element reference: stale elemen...\\n#18 0x55bf6ff955de \\u003Cunknown>\\n#19 0x7f7ecc09caa4 \\u003Cunknown>\\n#20 0x7f7ecc129c6c \\u003Cunknown>\\n"}}'}

    def check_response(self, response: Dict[str, Any]) -> None:
        """
        Checks that a JSON response from the WebDriver does not have an error.
    
        :Args:
         - response - The JSON response from the WebDriver server as a dictionary
           object.
    
        :Raises: If the response contains an error message.
        """
        status = response.get('status', None)
        if not status or status == ErrorCode.SUCCESS:
            return
        value = None
        message = response.get("message", "")
        screen: str = response.get("screen", "")
        stacktrace = None
        if isinstance(status, int):
            value_json = response.get('value', None)
            if value_json and isinstance(value_json, str):
                import json
                try:
                    value = json.loads(value_json)
                    if len(value.keys()) == 1:
                        value = value['value']
                    status = value.get('error', None)
                    if not status:
                        status = value.get("status", ErrorCode.UNKNOWN_ERROR)
                        message = value.get("value") or value.get("message")
                        if not isinstance(message, str):
                            value = message
                            message = message.get('message')
                    else:
                        message = value.get('message', None)
                except ValueError:
                    pass
    
        exception_class: Type[WebDriverException]
        if status in ErrorCode.NO_SUCH_ELEMENT:
            exception_class = NoSuchElementException
        elif status in ErrorCode.NO_SUCH_FRAME:
            exception_class = NoSuchFrameException
        elif status in ErrorCode.NO_SUCH_SHADOW_ROOT:
            exception_class = NoSuchShadowRootException
        elif status in ErrorCode.NO_SUCH_WINDOW:
            exception_class = NoSuchWindowException
        elif status in ErrorCode.STALE_ELEMENT_REFERENCE:
            exception_class = StaleElementReferenceException
        elif status in ErrorCode.ELEMENT_NOT_VISIBLE:
            exception_class = ElementNotVisibleException
        elif status in ErrorCode.INVALID_ELEMENT_STATE:
            exception_class = InvalidElementStateException
        elif status in ErrorCode.INVALID_SELECTOR \
                or status in ErrorCode.INVALID_XPATH_SELECTOR \
                or status in ErrorCode.INVALID_XPATH_SELECTOR_RETURN_TYPER:
            exception_class = InvalidSelectorException
        elif status in ErrorCode.ELEMENT_IS_NOT_SELECTABLE:
            exception_class = ElementNotSelectableException
        elif status in ErrorCode.ELEMENT_NOT_INTERACTABLE:
            exception_class = ElementNotInteractableException
        elif status in ErrorCode.INVALID_COOKIE_DOMAIN:
            exception_class = InvalidCookieDomainException
        elif status in ErrorCode.UNABLE_TO_SET_COOKIE:
            exception_class = UnableToSetCookieException
        elif status in ErrorCode.TIMEOUT:
            exception_class = TimeoutException
        elif status in ErrorCode.SCRIPT_TIMEOUT:
            exception_class = TimeoutException
        elif status in ErrorCode.UNKNOWN_ERROR:
            exception_class = WebDriverException
        elif status in ErrorCode.UNEXPECTED_ALERT_OPEN:
            exception_class = UnexpectedAlertPresentException
        elif status in ErrorCode.NO_ALERT_OPEN:
            exception_class = NoAlertPresentException
        elif status in ErrorCode.IME_NOT_AVAILABLE:
            exception_class = ImeNotAvailableException
        elif status in ErrorCode.IME_ENGINE_ACTIVATION_FAILED:
            exception_class = ImeActivationFailedException
        elif status in ErrorCode.MOVE_TARGET_OUT_OF_BOUNDS:
            exception_class = MoveTargetOutOfBoundsException
        elif status in ErrorCode.JAVASCRIPT_ERROR:
            exception_class = JavascriptException
        elif status in ErrorCode.SESSION_NOT_CREATED:
            exception_class = SessionNotCreatedException
        elif status in ErrorCode.INVALID_ARGUMENT:
            exception_class = InvalidArgumentException
        elif status in ErrorCode.NO_SUCH_COOKIE:
            exception_class = NoSuchCookieException
        elif status in ErrorCode.UNABLE_TO_CAPTURE_SCREEN:
            exception_class = ScreenshotException
        elif status in ErrorCode.ELEMENT_CLICK_INTERCEPTED:
            exception_class = ElementClickInterceptedException
        elif status in ErrorCode.INSECURE_CERTIFICATE:
            exception_class = InsecureCertificateException
        elif status in ErrorCode.INVALID_COORDINATES:
            exception_class = InvalidCoordinatesException
        elif status in ErrorCode.INVALID_SESSION_ID:
            exception_class = InvalidSessionIdException
        elif status in ErrorCode.UNKNOWN_METHOD:
            exception_class = UnknownMethodException
        else:
            exception_class = WebDriverException
        if not value:
            value = response['value']
        if isinstance(value, str):
            raise exception_class(value)
        if message == "" and 'message' in value:
            message = value['message']
    
        screen = None  # type: ignore[assignment]
        if 'screen' in value:
            screen = value['screen']
    
        stacktrace = None
        st_value = value.get('stackTrace') or value.get('stacktrace')
        if st_value:
            if isinstance(st_value, str):
                stacktrace = st_value.split('\n')
            else:
                stacktrace = []
                try:
                    for frame in st_value:
                        line = self._value_or_default(frame, 'lineNumber', '')
                        file = self._value_or_default(frame, 'fileName', '<anonymous>')
                        if line:
                            file = "%s:%s" % (file, line)
                        meth = self._value_or_default(frame, 'methodName', '<anonymous>')
                        if 'className' in frame:
                            meth = "%s.%s" % (frame['className'], meth)
                        msg = "    at %s (%s)"
                        msg = msg % (meth, file)
                        stacktrace.append(msg)
                except TypeError:
                    pass
        if exception_class == UnexpectedAlertPresentException:
            alert_text = None
            if 'data' in value:
                alert_text = value['data'].get('text')
            elif 'alert' in value:
                alert_text = value['alert'].get('text')
            raise exception_class(message, screen, stacktrace, alert_text)  # type: ignore[call-arg]  # mypy is not smart enough here
>       raise exception_class(message, screen, stacktrace)
E       selenium.common.exceptions.StaleElementReferenceException: Message: stale element reference: stale element not found in the current frame
E         (Session info: chrome=147.0.7727.55)
E       Stacktrace:
E       #0 0x55bf6ff96b6a <unknown>
E       #1 0x55bf6f998265 <unknown>
E       #2 0x55bf6f99f111 <unknown>
E       #3 0x55bf6f9a195b <unknown>
E       #4 0x55bf6f9a1a03 <unknown>
E       #5 0x55bf6f9eccd0 <unknown>
E       #6 0x55bf6f9e0437 <unknown>
E       #7 0x55bf6f9dfe07 <unknown>
E       #8 0x55bf6fa33969 <unknown>
E       #9 0x55bf6f9de5cf <unknown>
E       #10 0x55bf6f9df391 <unknown>
E       #11 0x55bf6ff5c04b <unknown>
E       #12 0x55bf6ff5f00d <unknown>
E       #13 0x55bf6ff48808 <unknown>
E       #14 0x55bf6ff5fba0 <unknown>
E       #15 0x55bf6ff2f280 <unknown>
E       #16 0x55bf6ff83db8 <unknown>
E       #17 0x55bf6ff83f88 <unknown>
E       #18 0x55bf6ff955de <unknown>
E       #19 0x7f7ecc09caa4 <unknown>
E       #20 0x7f7ecc129c6c <unknown>

/opt/hostedtoolcache/Python/3.8.18/x64/lib/python3.8/site-packages/selenium/webdriver/remote/errorhandler.py:247: StaleElementReferenceException