Kuberwastaken/claurst · error
No active Chrome session. Run `/chrome connect` first.
Error message
No active Chrome session. Run `/chrome connect` first.
What it means
Thrown by `take_session` in src-rust/crates/commands/src/chrome.rs when no Chrome session is stored in the global SESSION mutex. Commands like navigate, screenshot, click, fill, and eval call take_session to pop the session from the global slot; `.take()` returns None when `connect` was never run or the session was not put back. The library requires an explicit `/chrome connect` step before any CDP operation.
Solutions
- Run `/chrome connect` first so a session is stored in the global slot.
- Ensure the Chrome binary is running with the remote debugging port before connecting.
- In code, check for an active session (or call connect) before invoking navigate/screenshot/click/fill/eval.
Example fix
// before /chrome navigate https://example.com // error: No active Chrome session // after /chrome connect /chrome navigate https://example.com
Defensive patterns
Strategy: validation
Validate before calling
// check the global session slot before running a command
if !chrome::has_active_session() {
chrome::connect(port)?;
} Type guard
fn has_session(s: &Option<ChromeSession>) -> bool { s.is_some() } Try / catch
match take_session() {
Ok(s) => operate(s),
Err(_) => connect_and_retry(),
} Prevention
- Always run connect before any chrome subcommand.
- Wrap multi-step chrome automation behind a helper that ensures connection first.
- Reconnect after Chrome restarts or long idle periods.
When it happens
Trigger: Calling any Chrome command (navigate, screenshot, click, fill, eval) before `/chrome connect` has stored a ChromeSession in the global SESSION slot.
Common situations: Fresh app start where the user issues `/chrome navigate` first; a previous session was consumed/failed and never restored; Chrome was closed between commands and session teardown removed it; a script calls subcommands out of order.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Missing code or state in OAuth callback
- --dangerously-skip-permissions cannot be used with…
- Failed to bind port
- OAuth callback timeout (5 minutes)
- Failed to accept connection
AI-assisted analysis of Kuberwastaken/claurst@b0637c97ec (2026-09-10).
Data as JSON: /api/errors/c953237e103b07b5.
Report an issue: GitHub.
Appendix: source
Thrown at src-rust/crates/commands/src/chrome.rs:100
return Err(anyhow::anyhow!("CDP error: {}", err));
}
return Ok(val);
}
// It's an event or different response — keep waiting.
}
}
// -----------------------------------------------------------------------
// Session take/restore helpers
//
// We avoid holding a MutexGuard across await points by taking ownership
// of the session, performing all async operations with it, then putting
// it back into the global.
// -----------------------------------------------------------------------
fn take_session() -> anyhow::Result<ChromeSession> {
SESSION.lock().take().ok_or_else(|| {
anyhow::anyhow!("No active Chrome session. Run `/chrome connect` first.")
})
}
fn store_session(s: ChromeSession) {
*SESSION.lock() = Some(s);
}
// -----------------------------------------------------------------------
// Public helpers called from the SlashCommand impl
// -----------------------------------------------------------------------
/// Connect to Chrome at the given port.
/// Picks the first available target (tab/page).
pub async fn connect(port: u16) -> anyhow::Result<String> {
let http_url = format!("http://localhost:{}/json/list", port);
let client = reqwest::Client::builder()
.timeout(std::time::Duration::from_secs(3))
.build()?;
View on GitHub (pinned to b0637c97ec)