t8y2/dbx · error

a batch cancellation token is always available

Error message

a batch cancellation token is always available

What it means

In upgrade_all_agent_drivers_with_registry, the code builds a batch cancellation token: either it owns one (created from begin_install_cancellation for the operation) or it receives one via batch_cancellation. The invariant is that one of the two is always Some, so .expect("a batch cancellation token is always available") panics if both are None — a programming/contract violation, not a runtime condition.

Source

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

        agents.iter().filter(|agent| agent.update_available).map(|agent| agent.db_type.clone()).collect();
    let total = updatable.len() as u32;

    // Use the command-scoped batch token when one was registered before the
    // registry fetch + blocker check, so a cancel fired during that setup is
    // observed. Otherwise register a token owned by this call keyed by a fresh
    // operation id so it cannot collide with another in-flight operation.
    let owned_operation_id: Option<String> =
        if operation_id.is_some() { None } else { Some(uuid::Uuid::new_v4().to_string()) };
    let effective_operation_id: &str = owned_operation_id.as_deref().or(operation_id).unwrap_or_default();
    let owned_batch: Option<Arc<AgentInstallCancellation>> = if batch_cancellation.is_some() {
        None
    } else {
        Some(am.begin_install_cancellation(&batch_cancellation_key(effective_operation_id)).await)
    };
    let active_batch_arc: Arc<AgentInstallCancellation> = owned_batch
        .clone()
        .or_else(|| batch_cancellation.cloned())
        .expect("a batch cancellation token is always available");
    let active_batch: &AgentInstallCancellation = active_batch_arc.as_ref();
    if active_batch.is_cancelled() {
        if let Some(token) = owned_batch {
            am.finish_install_cancellation(&batch_cancellation_key(effective_operation_id), &token).await;
        }
        return Ok(UpgradeAllAgentDriversResult { cancelled: total, ..Default::default() });
    }

    // Register a per-driver token for every driver in the batch, keyed by the
    // batch operation id so per-driver cancels target this batch's driver even
    // when the same db_type is being installed concurrently elsewhere. The
    // batch token lets one click abort the whole upgrade; each driver token
    // lets the user cancel a single driver while the rest continue.
    let mut driver_cancellations = std::collections::HashMap::new();
    for db_type in &updatable {
        let key = batch_driver_cancellation_key(effective_operation_id, db_type);
        let token = am.begin_install_cancellation(&key).await;
        driver_cancellations.insert(db_type.clone(), token);

View on GitHub (pinned to c0390bff16)

Solutions

  1. Ensure every call path supplies either an operation id (so owned_batch is created) or a batch_cancellation token.
  2. If a caller legitimately has neither, generate an operation id / call begin_install_cancellation before invoking.
  3. Replace the expect with explicit error handling (return a generic token via begin_install_cancellation) if the invariant may not hold.
  4. Add a debug_assert/test covering all public callers to keep the invariant enforced.

Example fix

// before
let owned_batch = if cancelled_all { None } else {
    Some(am.begin_install_cancellation(&batch_cancellation_key(effective_operation_id)).await)
};
// after
effective_operation_id.get_or_insert_with(Uuid::new_v4);
let owned_batch = Some(am.begin_install_cancellation(&batch_cancellation_key(effective_operation_id)).await);
Defensive patterns

Strategy: validation

Validate before calling

// before calling the batch upgrade API, ensure a token source exists
debug!(operation_id = ?effective_operation_id, has_batch = batch_cancellation.is_some());
assert!(effective_operation_id.is_some() || batch_cancellation.is_some(),
    "batch upgrade requires an operation id or a batch cancellation token");

Type guard

fn has_batch_token(op_id: Option<&OperationId>, token: Option<&AgentInstallCancellation>) -> bool {
    op_id.is_some() || token.is_some()
}

Try / catch

// Rust panics are not catchable with try/catch; use catch_unwind at the boundary only
let result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(||
    upgrade_all_agent_drivers_from(...)
));
match result {
    Ok(inner) => inner,
    Err(_) => Err("batch upgrade panicked: missing cancellation token".into()),
}

Prevention

When it happens

Trigger: Calling upgrade_all_agent_drivers_with_registry (via upgrade_all_agent_drivers_from / _claimed, or the batch tests) with effective_operation_id = None AND batch_cancellation = None, i.e. an upgrade-all run that neither creates nor is handed a batch cancellation token.

Common situations: A refactor adds a new call site that passes no operation id and no shared batch token; tests invoke the registry upgrade path directly without going through the wrappers that always create the batch token; an operation-id plumbing bug makes effective_operation_id None in the batch path.

Related errors


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