SeleniumHQ/selenium · error · RuntimeError

{fn_name}() must be called in a session context.

Error message

{fn_name}() must be called in a session context.

What it means

Raised as a RuntimeError by get_session_context(fn_name) when the contextvars.ContextVar _session_context has no value set (LookupError). The CDP module uses session_context to implicitly route CDP commands to a specific target/session; CDP session-scoped functions call get_session_context to retrieve it. If called outside a session_context() block or an `async with connection.session(target):` context, no session is available.

Source

Thrown at py/private/cdp.py:105

    If there is no current connection, raise a ``RuntimeError`` with a
    helpful message.
    """
    try:
        return _connection_context.get()
    except LookupError:
        raise RuntimeError(f"{fn_name}() must be called in a connection context.")


def get_session_context(fn_name):
    """Look up the current session.

    If there is no current session, raise a ``RuntimeError`` with a
    helpful message.
    """
    try:
        return _session_context.get()
    except LookupError:
        raise RuntimeError(f"{fn_name}() must be called in a session context.")


@contextmanager
def connection_context(connection):
    """Context manager installs ``connection`` as the session context for the current Trio task."""
    token = _connection_context.set(connection)
    try:
        yield
    finally:
        _connection_context.reset(token)


@contextmanager
def session_context(session):
    """Context manager installs ``session`` as the session context for the current Trio task."""
    token = _session_context.set(session)
    try:
        yield

View on GitHub (pinned to aa36b38e69)

Solutions

  1. Ensure session-scoped CDP calls are inside `async with conn.session(target_id) as session:` or `with session_context(session):`.
  2. For background tasks or callbacks, explicitly set the session context within that task's scope.
  3. If you only need connection-level (not session-level) CDP calls, use the connection context instead (error 112).

Example fix

# before
async def main():
    conn = await Connection.create(url)
    session = await conn.connect_session(target_id)
    result = await runtime.evaluate('1+1')  # RuntimeError: no session

# after
async def main():
    conn = await Connection.create(url)
    async with conn.session(target_id) as session:
        result = await runtime.evaluate('1+1')  # session context set
Defensive patterns

Strategy: try-catch

Validate before calling

from selenium.webdriver.common.bidi.cdp import get_session_context
try:
    sess = get_session_context('check')
except RuntimeError:
    # enter a session context first
    pass

Try / catch

try:
    await runtime.evaluate('1+1')
except RuntimeError as e:
    if 'session context' in str(e):
        async with conn.session(target_id):
            await runtime.evaluate('1+1')
    else:
        raise

Prevention

When it happens

Trigger: Calling a CDP session-scoped function (e.g. dom.get_document() inside a session, runtime.evaluate on a specific target) outside of `with session_context(session):` or `async with conn.session(target_id):`. The ContextVar lookup raises LookupError which is re-raised as RuntimeError.

Common situations: Calling session-scoped CDP methods before entering the session context; code moved out of the `async with session:` block during refactoring; using CDP in a spawned Trio task that does not copy the contextvar; targeting multiple sessions and forgetting to switch context.

Related errors


AI-assisted analysis of SeleniumHQ/selenium@aa36b38e69 (2026-08-14). Data as JSON: /api/errors/bf9499ad08b6d4be. Report an issue: GitHub.