VLearnVibium

Fix: Vibium 'Port Already in Use'

Fix Vibium 'port already in use' errors — clean up orphaned Chrome and chromedriver processes, free the stuck port, and stop sessions leaking between runs.

By Pramod Dutta··4 min read·Verified with Vibium 26.2
▶ Animated overview · made with Remotion

To fix Vibium's "port already in use" error, kill the orphaned Chrome for Testing and chromedriver processes left over from a previous session, then relaunch — and prevent it permanently by calling vibe.quit() in a finally block. Vibium is AI-native browser automation built on a single Go binary that launches chromedriver and Chrome on a local port over WebDriver BiDi. A single session spawns 8 to 12 processes, and when a script is killed hard — Ctrl+C at the wrong moment, a kill -9, or a crash before cleanup runs — those child processes get reparented to PID 1 and keep holding the port. The next browser.launch() then collides with the still-running browser. Vibium already sweeps for these orphans on the next launch's cleanup, so often a simple retry works; when it does not, you kill the leftovers manually. Created by Jason Huggins, co-creator of Selenium and Appium, Vibium is designed to clean up its own process tree, so this error almost always traces back to an interrupted shutdown rather than a bug.

Why does Vibium report a port already in use?

The error happens because a previous Vibium session did not shut down cleanly and its chromedriver or Chrome process is still bound to the port the new session wants. When you kill a script with kill -9, Vibium never gets to run its cleanup, so Chrome and its helper processes are orphaned to PID 1 and linger. On the next run, the launcher tries to start a fresh browser on a port that the zombie still owns, and the launch fails. The fix is to remove the stuck processes so the port is released.

How do I find and kill the stuck processes?

List the leftover Chrome for Testing and chromedriver processes, confirm they are orphaned, then kill them. On macOS or Linux:

# See what's still running
pgrep -lf 'Chrome for Testing'
pgrep -lf chromedriver
 
# Confirm they're orphaned (PPID = 1 means orphaned)
ps -o pid,ppid,comm -p $(pgrep -f 'Chrome for Testing')
 
# Kill them all
pkill -f 'Chrome for Testing'
pkill -f chromedriver

After the processes are gone, the port is free and browser.launch() works again. If a script still complains, the simplest catch-all is to retry once — Vibium's next launch runs an orphan sweep as part of its own cleanup, which kills stragglers automatically.

How do I find what is holding the port directly?

If you want to target the port itself rather than process names, use lsof to find whatever owns it and kill that PID:

# Replace 9222 with the port from the error message
lsof -i :9222
 
# Kill the PID that lsof reports
kill -9 <PID>

This is useful when something other than a Vibium-spawned browser grabbed the port — for example a different debugging tool or a stale session from another project. Once lsof shows nothing on the port, relaunch your script.

How do I stop Vibium from leaking processes in the first place?

The permanent fix is to make sure vibe.quit() always runs, even when your script raises an error. Vibium kills the entire Chrome process tree on quit(), so a guaranteed shutdown prevents orphans and stuck ports:

from vibium import browser_sync as browser
 
vibe = browser.launch()
try:
    vibe.go("https://example.com")
    vibe.find("h1").text()
finally:
    vibe.quit()   # runs even if the body above raises

The finally block is the single most important habit for avoiding this error. Without it, any exception between launch() and quit() skips cleanup and orphans the browser. With it, the process tree is torn down on every run, success or failure.

Tips for avoiding stuck ports

  • Always quit() in a finally block so cleanup runs even on errors.
  • Avoid kill -9 on a running script — it skips Vibium's cleanup and orphans Chrome.
  • Retry once before debugging; Vibium sweeps orphans on the next launch.
  • Check pgrep -lf chromedriver after a crash to confirm nothing leaked.

For the exact shutdown behavior and any process-management options you are unsure about, see the official docs at vibium.com and github.com/VibiumDev/vibium.

Next steps

Frequently asked questions

Why does Vibium say the port is already in use?

Vibium launches chromedriver and Chrome on a local port. If a previous session was killed with Ctrl+C or kill -9 before it cleaned up, those processes stay alive and hold the port. The next launch then fails because the port it wants is still occupied by the orphaned browser.

How do I free a port stuck by Vibium?

Find and kill the leftover Chrome for Testing and chromedriver processes. Use pgrep to list them, then kill the PIDs, or run lsof to find whatever owns the port. Always quit Vibium in a finally block so sessions clean up automatically and never orphan a process again.

How do I stop Vibium from orphaning processes?

Call vibe.quit() in a finally block so cleanup runs even when your script errors. Vibium kills the whole Chrome process tree on quit and sweeps for orphans on the next launch, so a single clean shutdown usually prevents stuck ports entirely.

Vibium is created by Jason Huggins. This is an independent tutorial — see the official Vibium site and GitHub repo for canonical docs.

Related guides