Checklist before reporting
pydoll Version
2.22.1
Python Version
3.14
Operating System
Windows
Bug Description
It is impossible to access anything within the inner iframe of nested iframes, when the outer one is cross origin.
Steps to Reproduce
- Attach to chrome.. and navigate to a site with nested iframes such as https://nestedframes.netlify.app/. The outer iframe must be for a different domain than the website itself.
- use tab.find to find the outer iframe
- use outer_iframe.find to find the inner iframe
- use inner_iframe.find to find any element in the inner iframe -> pydoll.exceptions.InvalidIFrame: Unable to obtain document reference for iframe
Code Example
import asyncio
from pydoll.browser import Chrome
async def main():
async with Chrome() as chrome:
tab = await chrome.start()
await tab.go_to("https://nestedframes.netlify.app/")
# outer iframe
outer_iframe = await tab.find(id="outer_iframe")
outer_iframe_h1 = await outer_iframe.find(tag_name="h1")
print("Outer iframe H1 text: ", await outer_iframe_h1.text)
# inner iframe
inner_iframe = await outer_iframe.find(id="frame1")
inner_iframe_body = await inner_iframe.find(
tag_name="body"
) # pydoll.exceptions.InvalidIFrame: Unable to obtain document reference for iframe
print("Inner iframe body text: ", await inner_iframe_body.text)
if __name__ == "__main__":
asyncio.run(main())
Expected Behavior
Should resolve elements within the inner iframe properly and print the body text of the inner iframe: "Initial page"
Actual Behavior
No response
Relevant Log Output
(pyt) C:\Users\Admin\Downloads\Compressed\wayfern_146.0.7680.165_windows\wayfern-146.0.7680.164_windows_x64\pyt>uv run nested_iframe_bug.py
Outer iframe H1 text: Cross-site iframe test
Traceback (most recent call last):
File "C:\Users\Admin\Downloads\Compressed\wayfern_146.0.7680.165_windows\wayfern-146.0.7680.164_windows_x64\pyt\nested_iframe_bug.py", line 23, in <module>
asyncio.run(main())
~~~~~~~~~~~^^^^^^^^
File "C:\Users\Admin\AppData\Roaming\uv\python\cpython-3.14+freethreaded-windows-x86_64-none\Lib\asyncio\runners.py", line 204, in run
return runner.run(main)
~~~~~~~~~~^^^^^^
File "C:\Users\Admin\AppData\Roaming\uv\python\cpython-3.14+freethreaded-windows-x86_64-none\Lib\asyncio\runners.py", line 127, in run
return self._loop.run_until_complete(task)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^
File "C:\Users\Admin\AppData\Roaming\uv\python\cpython-3.14+freethreaded-windows-x86_64-none\Lib\asyncio\base_events.py", line 719, in run_until_complete
return future.result()
~~~~~~~~~~~~~^^
File "C:\Users\Admin\Downloads\Compressed\wayfern_146.0.7680.165_windows\wayfern-146.0.7680.164_windows_x64\pyt\nested_iframe_bug.py", line 18, in main
inner_iframe_body = await inner_iframe.find(tag_name="body")
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\Admin\Downloads\Compressed\wayfern_146.0.7680.165_windows\wayfern-146.0.7680.164_windows_x64\pyt\.venv\Lib\site-packages\pydoll\elements\mixins\find_elements_mixin.py", line 205, in find
return await self.find_or_wait_element(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
by, value, timeout=timeout, find_all=find_all, raise_exc=raise_exc
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
)
^
File "C:\Users\Admin\Downloads\Compressed\wayfern_146.0.7680.165_windows\wayfern-146.0.7680.164_windows_x64\pyt\.venv\Lib\site-packages\pydoll\elements\mixins\find_elements_mixin.py", line 341, in find_or_wait_element
return await find_method(by, value, raise_exc=raise_exc)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\Admin\Downloads\Compressed\wayfern_146.0.7680.165_windows\wayfern-146.0.7680.164_windows_x64\pyt\.venv\Lib\site-packages\pydoll\elements\mixins\find_elements_mixin.py", line 472, in _find_element
iframe_context = await element_self.iframe_context
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\Admin\Downloads\Compressed\wayfern_146.0.7680.165_windows\wayfern-146.0.7680.164_windows_x64\pyt\.venv\Lib\site-packages\pydoll\elements\web_element.py", line 241, in iframe_context
self._iframe_context = await resolver.resolve()
^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\Admin\Downloads\Compressed\wayfern_146.0.7680.165_windows\wayfern-146.0.7680.164_windows_x64\pyt\.venv\Lib\site-packages\pydoll\interactions\iframe.py", line 89, in resolve
document_object_id = await self._get_document_object_id(execution_context_id, context)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\Admin\Downloads\Compressed\wayfern_146.0.7680.165_windows\wayfern-146.0.7680.164_windows_x64\pyt\.venv\Lib\site-packages\pydoll\interactions\iframe.py", line 428, in _get_document_object_id
raise InvalidIFrame('Unable to obtain document reference for iframe')
pydoll.exceptions.InvalidIFrame: Unable to obtain document reference for iframe
Additional Context
When I asked a coding agent, I got this reproduction:
- The failure happens in pydoll/interactions/iframe.py:89 when _get_document_object_id() is called after createIsolatedWorld.
- In resolve(), session info is only written into context when _resolve_oopif_if_needed() returns a new OOPIF session (pydoll/interactions/iframe.py:77, pydoll/interactions/iframe.py:78, pydoll/interactions/iframe.py:79).
- But createIsolatedWorld is done with the effective session (session_id or base_session_id) (pydoll/interactions/iframe.py:81, pydoll/interactions/iframe.py:82, pydoll/interactions/iframe.py:84), so the execution context is created in the routed OOPIF session.
- Then _get_document_object_id() evaluates document.documentElement using context.session_id/context.session_handler (pydoll/interactions/iframe.py:419, pydoll/interactions/iframe.py:422), which are None in this nested case, so it runs on the wrong target and CDP returns “Cannot find context with specified id”, surfaced as InvalidIFrame.
- I confirmed this with runtime instrumentation: inner iframe had routing_session set, but context.session_id was None at document lookup time; also Page.createIsolatedWorld had a sessionId while the following Runtime.evaluate did not.
- I also validated the hypothesis by monkey-patching at runtime (no file edits): fallback to routing/effective session inside _get_document_object_id made your repro succeed (Inner: Initial page).
I don't really know the library internals very well so I am just putting it here in case it's useful to you.
Checklist before reporting
pydoll Version
2.22.1
Python Version
3.14
Operating System
Windows
Bug Description
It is impossible to access anything within the inner iframe of nested iframes, when the outer one is cross origin.
Steps to Reproduce
Code Example
Expected Behavior
Should resolve elements within the inner iframe properly and print the body text of the inner iframe: "Initial page"
Actual Behavior
No response
Relevant Log Output
Additional Context
When I asked a coding agent, I got this reproduction:
I don't really know the library internals very well so I am just putting it here in case it's useful to you.