Skip to content

[Bug]: Cannot access nested iframes when other iframe #406

@SZRabinowitz

Description

@SZRabinowitz

Checklist before reporting

  • I have searched for similar issues and didn't find a duplicate.
  • I have updated to the latest version of pydoll to verify the issue still exists.

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

  1. 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.
  2. use tab.find to find the outer iframe
  3. use outer_iframe.find to find the inner iframe
  4. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions