{"record":{"id":"fc9f270e01ddb87d","repo":"D4Vinci/Scrapling","slug":"session-session-id-already-exists-use-a-diffe","errorCode":null,"errorMessage":"Session '{session_id}' already exists. Use a different ID or close the existing session first.","messagePattern":"Session '(.+?)' already exists\\. Use a different ID or close the existing session first\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"scrapling/core/ai.py","lineNumber":235,"sourceCode":"        :param useragent: Pass a useragent string to be used. Otherwise the fetcher will generate a real Useragent of the same browser and use it.\n        :param cdp_url: Instead of launching a new browser instance, connect to this CDP URL to control real browsers through CDP.\n        :param executable_path: Absolute path to a custom Chromium-compatible browser executable. Overrides the server-wide default for this session.\n        :param timeout: The timeout in milliseconds that is used in all operations and waits through the page. The default is 30,000.\n        :param disable_resources: Drop requests for unnecessary resources for a speed boost.\n        :param wait_selector: Wait for a specific CSS selector to be in a specific state.\n        :param cookies: Set cookies for the session. It should be in a dictionary format that Playwright accepts.\n        :param network_idle: Wait for the page until there are no network connections for at least 500 ms.\n        :param wait_selector_state: The state to wait for the selector given with `wait_selector`. The default state is `attached`.\n        :param max_pages: Maximum number of concurrent pages/tabs in the browser. Defaults to 5. Higher values allow more parallel fetches.\n        :param hide_canvas: (Stealthy only) Add random noise to canvas operations to prevent fingerprinting.\n        :param block_webrtc: (Stealthy only) Forces WebRTC to respect proxy settings to prevent local IP address leak.\n        :param allow_webgl: (Stealthy only) Enabled by default. Disabling WebGL is not recommended as many WAFs now check if WebGL is enabled.\n        :param solve_cloudflare: (Stealthy only) Solves all types of the Cloudflare's Turnstile/Interstitial challenges.\n        :param additional_args: (Stealthy only) Additional arguments to be passed to Playwright's context as additional settings.\n        \"\"\"\n        session_id = session_id or uuid4().hex[:12]\n        if session_id in self._sessions:\n            raise ValueError(\n                f\"Session '{session_id}' already exists. Use a different ID or close the existing session first.\"\n            )\n\n        common_kwargs: Dict[str, Any] = dict(\n            wait=wait,\n            proxy=proxy,\n            locale=locale,\n            timeout=timeout,\n            cookies=cookies,\n            cdp_url=cdp_url,\n            headless=headless,\n            block_ads=True,\n            max_pages=max_pages,\n            useragent=useragent,\n            timezone_id=timezone_id,\n            real_chrome=real_chrome,\n            network_idle=network_idle,\n            wait_selector=wait_selector,","sourceCodeStart":217,"sourceCodeEnd":253,"githubUrl":"https://github.com/D4Vinci/Scrapling/blob/5d213a2d4764002bfc4fed33c32fe09fa8b0bf7f/scrapling/core/ai.py#L217-L253","documentation":"open_session generates a random 12-hex-char ID when none is supplied, but if a caller-provided session_id already exists in the registry it raises this ValueError to prevent silently hijacking an existing browser session. Duplicate IDs would otherwise alias two live sessions and corrupt resource tracking.","triggerScenarios":"Calling open_session twice with the same explicit session_id without closing the first, e.g. deterministic IDs like 'main' reused across retry loops or repeated agent turns.","commonSituations":"Agents using fixed session names ('default', 'browser') across steps, or retry logic that re-invokes open_session after a partial failure while the first session actually opened fine.","solutions":["Check list_sessions and reuse the existing session instead of reopening","Or close_session(id) first, then open again with the same ID","Omit session_id to let Scrapling generate a unique one, and store the returned ID"],"exampleFix":"# before\nawait open_session(session_type='dynamic', session_id='main')\nawait open_session(session_type='dynamic', session_id='main')  # ValueError: already exists\n\n# after\nexisting = {s.session_id for s in await list_sessions()}\nif 'main' not in existing:\n    await open_session(session_type='dynamic', session_id='main')","handlingStrategy":"validation","validationCode":"if any(s.session_id == 'main' for s in await list_sessions()):\n    await close_session('main')\nawait open_session(session_type='dynamic', session_id='main')","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Prefer generated IDs (omit session_id) and track returned values","In retry loops, check list_sessions before re-opening with a fixed ID"],"tags":["ai","mcp","session","duplicate","input-validation"],"backgroundTag":null,"analyzedSha":"5d213a2d4764002bfc4fed33c32fe09fa8b0bf7f","analyzedAt":"2026-08-14T22:23:09.440Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}