databendlabs/databend · error

expect cluster.

Error message

expect cluster.

What it means

QueryContextShared::get_warehouse_clusters caches the warehouse cluster info in `warehouse_cache`. After inserting the cloned warehouse when the cache was None, it re-reads and unwraps with expect("expect cluster.") — the value must exist immediately after insertion. The panic means the RwLock write guard saw a contradictory state (None after being set), e.g. lock released between check and read or concurrent clearing.

Solutions

  1. Return the local `warehouse.clone()` directly instead of re-reading the guard, eliminating the impossible unwrap.
  2. Check cluster/warehouse configuration stability; avoid reconfiguring warehouses while queries run.
  3. If persistent, capture stack trace and report as a concurrency bug in query_ctx_shared.
  4. Restart the query/node if the cache got into a bad state.

Example fix

// before
if write_guard.is_none() { *write_guard = Some(warehouse.clone()); }
Ok(write_guard.as_ref().cloned().expect("expect cluster."))
// after
if write_guard.is_none() { *write_guard = Some(warehouse.clone()); }
Ok(warehouse)
Defensive patterns

Strategy: fallback

Validate before calling

// confirm warehouse/cluster is configured before running queries
SELECT * FROM system.clusters;

Type guard

fn cluster_cached(s: &QueryContextShared) -> bool { s.warehouse_cache.read().is_some() }

Try / catch

// prefer returning the already-cloned value instead of re-unwrapping:
Ok(warehouse)

Prevention

When it happens

Trigger: Concurrent mutation of warehouse_cache between the write_guard set and the as_ref().cloned() read within the same guard (shouldn't happen), or code path where warehouse clone failed/cleared the cache, breaking the just-set invariant.

Common situations: Multi-threaded query execution in a managed/warehouse-mode deployment racing on the shared context; unusual cluster/warehouse reconfiguration at runtime.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of databendlabs/databend@288d84d76e (2026-09-11). Data as JSON: /api/errors/92236383dccae6a8. Report an issue: GitHub.

Appendix: source

Thrown at src/query/service/src/sessions/query_ctx_shared.rs:341

        self.cluster_cache.read().clone()
    }

    pub async fn get_warehouse_clusters(&self) -> Result<Arc<Cluster>> {
        if let Some(warehouse) = self.warehouse_cache.read().as_ref() {
            return Ok(warehouse.clone());
        }

        let config = GlobalConfig::instance();
        let discovery = ClusterDiscovery::instance();
        let warehouse = discovery.discover_warehouse_nodes(&config).await?;

        let mut write_guard = self.warehouse_cache.write();

        if write_guard.is_none() {
            *write_guard = Some(warehouse.clone());
        }

        Ok(write_guard.as_ref().cloned().expect("expect cluster."))
    }

    pub fn get_current_catalog(&self) -> String {
        self.session.get_current_catalog()
    }

    pub fn set_current_catalog(&self, catalog_name: String) {
        self.session.set_current_catalog(catalog_name)
    }

    pub fn get_aborting(&self) -> Arc<AtomicBool> {
        self.aborting.clone()
    }

    pub fn check_aborting(&self) -> Result<(), ContextError> {
        if self.aborting.load(Ordering::Acquire) {
            Err(self
                .get_error()

View on GitHub (pinned to 288d84d76e)