What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.
A Selenium “session does not exist” error means your command reached a WebDriver session ID that the browser driver no longer recognizes. In Python this is usually reported as selenium.common.exceptions.InvalidSessionIdException. The reliable fix is to find where the session was deleted or changed, stop sending commands through that driver, and create a new session when the next unit of work starts.
What the error actually means
Every WebDriver instance has a session ID. Selenium sends that ID with commands such as navigation, element lookup and screenshots. The remote end (the local driver or a Selenium Grid node) keeps a map of active IDs. If the ID has been removed, a command cannot be routed and the remote end returns the WebDriver invalid session id error.
This is a lifecycle problem, not an element-locator problem. A selector can be perfectly valid and still fail if the driver session has already ended. Selenium’s Python binding maps the wire error to InvalidSessionIdException.
Free tools Windows power users keep installed
One-click scans. No signup required.
Fix it in the right order
- Locate the first teardown or window close. Search the test, fixtures, hooks and helper functions for
driver.quit()anddriver.close(). Then find the first browser command that runs afterward. - Keep cleanup at the end of the work unit. Put
quit()in the test framework’s teardown hook or afinallyblock. Do not use the same driver object after that call. - Check the browser-window lifecycle. Closing the final top-level tab or window can end or change the session state. If a helper calls
close(), verify that another window remains before continuing. - For Grid, inspect the remote state. Check the Grid status and session endpoints, confirm that the node still has the session and that your client is using the correct Grid address.
- Separate it from startup failures. A
SessionNotCreatedExceptionhappens while creating a session, commonly during browser/driver compatibility or configuration problems. It is not the same as an already-created session disappearing.
Common cause: a command runs after quit()
The failing pattern
from selenium import webdriver
driver = webdriver.Chrome()
driver.get("https://example.com")
driver.quit()
# The session ID was deleted; this raises InvalidSessionIdException.
driver.title
quit() ends the WebDriver session and closes every window owned by it. Retrying driver.title, get() or another command cannot revive that ID.
#1 Best Overall
The safe pattern
from selenium import webdriver
def run_check(url: str) -> str:
driver = webdriver.Chrome()
try:
driver.get(url)
return driver.title
finally:
driver.quit()
print(run_check("https://example.com"))
The finally block runs on assertion failures and unexpected exceptions, so the session is cleaned up without leaving a browser process behind. A later test should call webdriver.Chrome() (or the appropriate driver constructor) to obtain a new session.
Common cause: close() removed the last browsing context
close() closes the current tab or window, while quit() ends the entire session. If the current context is the last one, the browser has no top-level context left and the remote end may delete or change the session. Code that assumes the original window still exists then produces an invalid-session error.
Close one window, then switch deliberately
from selenium import webdriver
driver = webdriver.Chrome()
try:
driver.get("https://example.com")
original = driver.current_window_handle
driver.execute_script("window.open('https://www.python.org', '_blank');")
handles = driver.window_handles
new_handle = next(handle for handle in handles if handle != original)
driver.switch_to.window(new_handle)
driver.close() # closes only the second tab
driver.switch_to.window(original) # continue in the surviving tab
print(driver.title)
finally:
driver.quit()
Before calling close(), decide whether another handle will remain. After closing, switch to a handle that is still present; never keep issuing commands against a closed context.
Quick wins for a faster PC:
Repair Windows errors before they cause bigger problemsFix Now →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Rank #2
Fixture and teardown-order mistakes
Use one ownership rule
Only one layer should own session cleanup. If a fixture calls quit() and a test or helper also calls it, later code may accidentally reuse the dead object. Pass a driver into helpers, but do not let helpers silently terminate it unless that ownership is explicit.
import pytest
from selenium import webdriver
@pytest.fixture
def driver():
instance = webdriver.Chrome()
yield instance
instance.quit()
def test_homepage_title(driver):
driver.get("https://example.com")
assert driver.title
With this fixture, the test uses the session during its body and the fixture performs teardown afterward. Remove any quit() call from the test itself unless the fixture is changed accordingly.
Watch for hidden cleanup paths
- Failure handlers that capture a screenshot and then quit before the main assertion or logger runs.
- Helpers that use
with webdriver.Chrome() as driver:and return the driver outside thewithblock. - Parameterized tests that retain a driver from a previous iteration.
- Parallel workers sharing a driver object instead of creating one session per worker.
Diagnose Selenium Grid and remote WebDriver sessions
On Grid, the client’s session ID is mapped to a remote node. A deleted session is removed from the active-session map, so requests carrying that ID fail even if the client process is still running. A node can also disappear or become unavailable while the test is executing.
Rank #3
What to inspect
| Context | First checks | Evidence |
|---|---|---|
| Local WebDriver | Premature quit(), closing the final tab, teardown order |
Test code, fixtures, hooks and window handles |
| Selenium Grid / remote WebDriver | Session deletion, node availability and routing address | Grid status, active-session data and node logs |
Use the Grid status endpoint documented for your Selenium version to verify that the node is available and that the session is listed. Confirm the client is connecting to the same Grid address that created the session. If an administrator or cleanup job deleted the session, create a new one; do not repeatedly retry commands with the old ID.
Hosted browser services
Third-party providers may impose their own idle, maximum-duration or queue limits. Selenium’s general documentation does not establish one timeout policy for every provider. Check that provider’s session log and timeout settings before changing retry logic. Treat a provider-reported termination as a new-session event unless its documentation explicitly supports recovery.
Recovery: start a fresh session and restore state
Once a session is deleted, recovery means reconstructing the browser state your test needs. A robust retry boundary is the whole workflow, not the single failed command.
Rank #4
from selenium import webdriver
from selenium.common.exceptions import InvalidSessionIdException
def fetch_title(url: str) -> str:
driver = webdriver.Chrome()
try:
driver.get(url)
return driver.title
finally:
driver.quit()
def fetch_with_one_recovery(url: str) -> str:
try:
return fetch_title(url)
except InvalidSessionIdException:
# The old session cannot be repaired; create a completely new one.
return fetch_title(url)
print(fetch_with_one_recovery("https://example.com"))
Keep retries limited. If every new session fails, investigate browser startup, Grid capacity, network access and provider logs rather than adding an unbounded loop. Reapply cookies, authentication, local storage, window size and navigation steps in the new session as required by the test.
Distinguish invalid-session errors from startup errors
| Exception or symptom | When it occurs | What to do |
|---|---|---|
InvalidSessionIdException |
After a session was created, a command uses an ID the remote end no longer knows | Find quit(), final-window close(), remote deletion or node loss; create a new session |
SessionNotCreatedException |
During session creation | Check browser/driver compatibility, capabilities, binary paths and Grid configuration |
| Element or window errors | Session remains valid, but the requested target is absent | Check waits, selectors and current window/frame; do not treat it as session deletion |
Practical troubleshooting checklist
- Log the point at which the driver is created, each
quit()/close(), and the current window handles. - Search all fixtures, hooks and exception handlers, not only the test body.
- Assert that the driver is not used after a context manager or teardown returns.
- For Grid, record the session ID, Grid URL, node and timestamps from client and server logs.
- Check whether a final tab was closed before a later command.
- Replace the dead driver with a newly constructed one; do not mutate or reuse the old instance.
- Preserve only the state you can safely recreate, such as the URL, credentials setup and test data.
Or skip the browser setup
If your goal is a clean image or PDF rather than interactive browser automation, ScreenshotNeo makes one HTTP request and returns the capture. It accepts cookie and consent banners before the shot, removes more than 60 known consent platforms plus newsletter popups and chat widgets, and lets you turn those steps off. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads and cache hits are not billed; response headers report the page verdict and billing result. Its MCP server includes take_screenshot, get_page_info and capture_pdf for Claude, Cursor and other MCP clients.
Use the same API from any language. See the complete parameter reference in the ScreenshotNeo documentation.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
The Free plan includes 1,000 shots per month with no card. Paid plans start at $5 for 3,000 shots; every feature is available on every plan. Create a free ScreenshotNeo account.
Best Value
Frequently Asked Questions
Can I fix an invalid session ID by calling driver.get() again?
No. If the remote end deleted the session, commands using that ID cannot restore it. Construct a new driver and repeat the required setup.
Does driver.close() always invalidate Selenium?
No. It closes only the current window. The risk is closing the final top-level window or continuing without switching to a surviving handle.
The Tool Desk
Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Should I catch InvalidSessionIdException around every Selenium command?
Usually not. Catch it at a workflow boundary where you can create a new session and restore state; broad per-command retries can hide a teardown-order bug.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

