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
- Call list_sessions first and use one of the returned session_id values
- If the list is empty or the ID is missing, open_session again and use the new ID
- Open sessions with an explicit session_id you control so IDs are predictable and loggable
- 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
- Always call list_sessions before reusing an ID across agent turns
- Store the session_id returned by open_session; never hand-type IDs
- Assume all sessions are invalid after an MCP server restart
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
- Session '{session_id}' is no longer alive. Open a new sessio
- Session '{session_id}' is a '{entry.session_type}' session,
- Session '{session_id}' already exists. Use a different ID or
- Credentials dictionary must contain both 'username' and 'pas
- 'quality' is only valid when 'image_type' is 'jpeg'.
AI-assisted analysis of D4Vinci/Scrapling@5d213a2d47 (2026-08-14).
Data as JSON: /api/errors/49c20e8263cd2e5e.
Report an issue: GitHub.