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
- Return the local `warehouse.clone()` directly instead of re-reading the guard, eliminating the impossible unwrap.
- Check cluster/warehouse configuration stability; avoid reconfiguring warehouses while queries run.
- If persistent, capture stack trace and report as a concurrency bug in query_ctx_shared.
- 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
- Avoid runtime warehouse reconfiguration while queries execute
- Use the local value instead of re-reading the just-written cache
- Monitor for concurrent context-sharing across threads
- Report persistent hits as concurrency bugs
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
- rename_database: src (db) should exist
- unexpected value type for grouping function
- Unsupported unit
- internal error: entered unreachable code
- internal error: entered unreachable code
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)