t8y2/dbx · error

driver operation lock table poisoned

Error message

driver operation lock table poisoned

What it means

driver_operation_lock acquires the process-wide driver_operation_locks table guarded by a std::sync::Mutex. .lock() returns Err (poisoned) if another thread panicked while holding the mutex; the expect("driver operation lock table poisoned") then panics in turn. It signals that some earlier driver-operation code path panicked while mutating the lock table.

Source

Thrown at crates/dbx-core/src/agent_service.rs:893

    progress(AgentProgressEvent::step("all-done"));
    Ok(result)
}

fn is_cancelled_error(error: &str) -> bool {
    error.contains(AGENT_DOWNLOAD_CANCELED_ERROR)
}

async fn can_fallback_to_local_agent(
    _am: &AgentManager,
    _db_type: &str,
    cancellations: &[&AgentInstallCancellation],
) -> bool {
    !cancellations.iter().any(|token| token.is_cancelled())
}

fn driver_operation_lock<'a>(am: &'a AgentManager, db_type: &str) -> OperationLockHandle<'a> {
    let mut locks = am.driver_operation_locks.lock().expect("driver operation lock table poisoned");
    let lock = locks.entry(db_type.to_string()).or_insert_with(|| Arc::new(tokio::sync::Mutex::new(()))).clone();
    OperationLockHandle::new(&am.driver_operation_locks, db_type, lock)
}

fn jre_operation_lock<'a>(am: &'a AgentManager, jre_key: &str) -> OperationLockHandle<'a> {
    let mut locks = am.jre_install_locks.lock().expect("JRE install lock table poisoned");
    let lock = locks.entry(jre_key.to_string()).or_insert_with(|| Arc::new(tokio::sync::Mutex::new(()))).clone();
    OperationLockHandle::new(&am.jre_install_locks, jre_key, lock)
}

/// Future that resolves as soon as any cancellation token fires.
fn first_cancellation<'a>(
    cancellations: &'a [&'a AgentInstallCancellation],
) -> std::pin::Pin<Box<dyn std::future::Future<Output = ()> + Send + 'a>> {
    Box::pin(async move {
        let ((), _index, _rest) =
            futures::future::select_all(cancellations.iter().map(|token| Box::pin(token.cancelled()))).await;
    })

View on GitHub (pinned to c0390bff16)

Solutions

  1. Find and fix the original panic that poisoned the mutex — the poisoned-guard payload usually contains it.
  2. If resilience is needed, use lock().unwrap_or_else(|p| p.into_inner()) to recover, since the table is just an entry map.
  3. Prefer scoped locking that avoids panicking while the guard is held (no expect/unwrap inside the critical section).
  4. Consider a parking_lot::Mutex (non-poisoning) for lock tables like this.

Example fix

// before
let mut locks = am.driver_operation_locks.lock().expect("driver operation lock table poisoned");
// after
let mut locks = am.driver_operation_locks.lock().unwrap_or_else(|poisoned| poisoned.into_inner());
Defensive patterns

Strategy: try-catch

Validate before calling

// detect poisoning early in health checks
if am.driver_operation_locks.is_poisoned() {
    tracing::error!("driver_operation_locks mutex is poisoned; restart or recover");
}

Type guard

fn lock_table_healthy(locks: &std::sync::Mutex<DriverLockTable>) -> bool {
    !locks.is_poisoned()
}

Try / catch

let mut locks = am.driver_operation_locks.lock().unwrap_or_else(|poisoned| {
    tracing::warn!("driver lock table was poisoned; recovering: {:?}", poisoned);
    poisoned.into_inner()
});

Prevention

When it happens

Trigger: Any driver operation (install_agent_driver_with_batch, uninstall_agent_driver, import_agent_driver, ensure_agent_driver_ready_from, install_agent_driver_from_registry_locked) panics while holding the driver_operation_locks mutex; the next caller of driver_operation_lock then hits the poisoned lock and panics.

Common situations: An earlier install/uninstall panicked (bug, assertion, failed expect like 1082) and left the mutex poisoned; subsequent operations that should work now cascade-fail; in tests this shows as an unexpected panic on the second operation after a deliberately panicking case.

Related errors


AI-assisted analysis of t8y2/dbx@c0390bff16 (2026-09-05). Data as JSON: /api/errors/a13da6aa8c5bdae0. Report an issue: GitHub.