nikivdev/code · error
open jazz2 failed
Error message
open jazz2 failed
What it means
open_db_with_retry retries opening the jazz2 SQLite database on lock errors (sleeping 60ms between attempts); if all retries fail, it returns the last error, or this error when no error was captured. It indicates the database could not be opened after exhausting retries.
Source
Thrown at src/jazz_state.rs:95
}
let db = Database::new(env);
save_catalog_id(&path, db.catalog_object_id())?;
Ok(db)
}
fn open_db_with_retry() -> Result<Database> {
let mut last_err: Option<anyhow::Error> = None;
for _ in 0..3 {
match open_db() {
Ok(db) => return Ok(db),
Err(err) => {
last_err = Some(err);
thread::sleep(Duration::from_millis(60));
}
}
}
Err(last_err.unwrap_or_else(|| anyhow::anyhow!("open jazz2 failed")))
}
fn is_lock_error(err: &anyhow::Error) -> bool {
err.chain().any(|cause| {
let msg = cause.to_string().to_lowercase();
msg.contains("lock") || msg.contains("resource temporarily unavailable")
})
}
pub fn state_dir() -> PathBuf {
if let Ok(path) = std::env::var("FLOW_JAZZ2_PATH") {
return config::expand_path(&path);
}
let repo_root = config::expand_path(DEFAULT_REPO_ROOT);
if repo_root.exists() {
return repo_root.join(".jazz2");
}
std::env::var_os("HOME")View on GitHub (pinned to a747e741ae)
Solutions
- Close other processes using jazz2 (other f invocations, DB browsers) and retry
- Check file permissions and that the jazz2 file/directory are writable and not corrupt (try opening with sqlite3)
- Increase retry count/backoff in open_db_with_retry for heavy concurrency
- Restore or delete/recreate a corrupted jazz2 database
Example fix
// before
Err(last_err.unwrap_or_else(|| anyhow::anyhow!("open jazz2 failed")))
// after
Err(last_err.unwrap_or_else(|| anyhow::anyhow!("open jazz2 failed: unknown cause, check db file permissions and concurrent processes"))) Defensive patterns
Strategy: retry
Validate before calling
let db_path = std::path::Path::new("jazz2");
if !db_path.exists() { anyhow::bail!("jazz2 database missing"); }
let meta = std::fs::metadata(db_path)?;
if meta.permissions().readonly() { anyhow::bail!("jazz2 is read-only"); } Try / catch
match with_db(|db| record_task_run(db, rec)) {
Err(e) if e.to_string().contains("open jazz2 failed") || e.to_string().to_lowercase().contains("lock") => {
std::thread::sleep(Duration::from_millis(500));
with_db(|db| record_task_run(db, rec))?; // one extra outer retry
}
other => other?,
} Prevention
- Avoid running many concurrent f processes against the same jazz2
- Add exponential backoff to open retries
- Monitor for stale locks after killed processes
When it happens
Trigger: Opening src/jazz2 while another process holds an exclusive lock beyond the retry window, corrupt DB file, permission denied, or directory missing — so every open attempt fails and the loop exits with last_err set (or None).
Common situations: Concurrent CLI invocations contending on jazz2, stale lock from a killed process, read-only filesystem, DB file corrupted after a crash.
Related errors
- create table failed: {:?}
- DATABASE_URL not found (set env, PLANETSCALE_DATABASE_URL, o
- insert failed: {:?}
AI-assisted analysis of nikivdev/code@a747e741ae (2026-09-01).
Data as JSON: /api/errors/265f0b39f14aea0d.
Report an issue: GitHub.