D4Vinci/Scrapling · error · ValueError

Session '{session_id}' not found. Use list_sessions to see a

Error message

Session '{session_id}' not found. Use list_sessions to see active sessions.

What it means

The MCP browser-session manager keeps sessions in a dict keyed by session_id. _get_session raises this ValueError when the ID is absent — i.e. the session was never opened in this server process, was closed, or belongs to a different run. Every tool that operates on an existing session (fetch in session, screenshot, close) goes through this lookup.

Source

Thrown at scrapling/core/ai.py:165

        :param executable_path: Optional global Chromium-compatible browser executable path for browser tools.
            If omitted, the SCRAPLING_EXECUTABLE_PATH environment variable is used when set.
        :param auth_token: Optional shared token that clients must send as `Authorization: Bearer <token>`.
            If omitted, the SCRAPLING_MCP_AUTH_TOKEN environment variable is used when set. It only applies
            to the streamable-http transport.
        """
        self._sessions: Dict[str, _SessionEntry] = {}
        self._executable_path = executable_path or environ.get(MCP_EXECUTABLE_PATH_ENV) or None
        self._auth_token = auth_token or environ.get(MCP_AUTH_TOKEN_ENV) or None

    def _resolve_executable_path(self, executable_path: Optional[str]) -> Optional[str]:
        """Return a per-call executable path or the server-wide default."""
        return executable_path or self._executable_path

    def _get_session(self, session_id: str, expected_type: Optional[SessionType]) -> _SessionEntry:
        """Look up a session by ID, optionally validating its type. Pass `None` to skip the type check."""
        entry = self._sessions.get(session_id)
        if entry is None:
            raise ValueError(f"Session '{session_id}' not found. Use list_sessions to see active sessions.")
        if not entry.session._is_alive:
            raise ValueError(f"Session '{session_id}' is no longer alive. Open a new session.")
        if expected_type is not None and entry.session_type != expected_type:
            raise ValueError(
                f"Session '{session_id}' is a '{entry.session_type}' session, but this tool requires a "
                f"'{expected_type}' session. Use the matching fetch tool for your session type."
            )
        return entry

    async def open_session(
        self,
        session_type: SessionType,
        session_id: Optional[str] = None,
        headless: bool = True,
        google_search: bool = True,
        real_chrome: bool = False,
        wait: int | float = 0,
        proxy: Optional[str | Dict[str, str]] = None,

View on GitHub (pinned to 5d213a2d47)

Solutions

  1. Call list_sessions first and use one of the returned session_id values
  2. If the list is empty or the ID is missing, open_session again and use the new ID
  3. Open sessions with an explicit session_id you control so IDs are predictable and loggable
  4. After any MCP server restart, treat all previous session IDs as invalid

Example fix

# before
await screenshot_session(session_id='abc123', url='https://example.com')
# ValueError: Session 'abc123' not found...

# after
infos = await list_sessions()
sid = infos[0].session_id if infos else (await open_session('session_type'='dynamic')).session_id
await screenshot_session(session_id=sid, url='https://example.com')
Defensive patterns

Strategy: validation

Validate before calling

sessions = {s.session_id: s for s in await list_sessions()}
if session_id not in sessions:
    opened = await open_session(session_type='dynamic')
    session_id = opened.session_id

Try / catch

try:
    result = await fetch_with_session(session_id=sid, url=url)
except ValueError as e:
    if 'not found' in str(e):
        sid = (await open_session(session_type='dynamic')).session_id
        result = await fetch_with_session(session_id=sid, url=url)
    else:
        raise

Prevention

When it happens

Trigger: Calling screenshot_session/fetch_with_session/close_session with a session_id that was never opened, was already closed (or auto-closed after a crash), or after the MCP server restarted (in-memory registry wiped). Also using an ID from a different server instance.

Common situations: LLM agents reusing a stale session ID across conversation turns after the server restarted, IDs truncated/typo'd when copied, or two clients sharing one MCP server and mixing up IDs.

Related errors


AI-assisted analysis of D4Vinci/Scrapling@5d213a2d47 (2026-08-14). Data as JSON: /api/errors/49c20e8263cd2e5e. Report an issue: GitHub.