databendlabs/databend · error

QueryInfo is none

Error message

QueryInfo is none

What it means

`get_fragment_source` looks up the query coordinator by id and expects its `info` (holding query_ctx) to exist, panicking with `expect("QueryInfo is none")` otherwise. The invariant: any coordinator visible in the map has been fully initialized with QueryInfo before fragments are subscribed.

Solutions

  1. Check whether the query was concurrently cancelled or its init failed; look for the earlier error in logs for the same query id.
  2. Guard the request path: return `ErrorCode::Internal("Query info not ready")` (or query-not-exists) instead of panicking when info is None.
  3. Ensure init_query_env sets info before the coordinator becomes visible to fragment requests (ordering fix).
  4. Retry the query on a healthy node if the state resulted from a transient failure.

Example fix

// before
.expect("QueryInfo is none")
// after
.ok_or_else(|| ErrorCode::Internal(format!("QueryInfo is none for query {query_id}")))?
Defensive patterns

Strategy: try-catch

Validate before calling

// caller-side: confirm query still exists and is initialized before requesting fragments
// match coordinator.info { None => return Err(...), Some(_) => proceed }

Type guard

fn coordinator_ready(c: &QueryCoordinator) -> bool { c.info.is_some() }

Try / catch

let info = query_coordinator.info.as_ref().ok_or_else(||
    ErrorCode::Internal(format!("query {query_id} not initialized")))?;

Prevention

When it happens

Trigger: A fragment source request (e.g. `get_fragment_source` during pipeline execution) arrives for a query whose coordinator was registered but whose QueryInfo/context was not yet set or was already removed — a setup/teardown race on the same node.

Common situations: Query cancelled/timed out while fragments still request sources; init_query_env failed partway after registration; retry or duplicate fragment requests arriving after coordinator teardown.

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/a577dac47a7574bb. Report an issue: GitHub.

Appendix: source

Thrown at src/query/service/src/servers/flight/v1/exchange/exchange_manager.rs:1007

        }
    }

    pub fn get_fragment_source(
        &self,
        query_id: &str,
        fragment_id: usize,
        injector: Arc<dyn ExchangeInjector>,
    ) -> Result<PipelineBuildResult> {
        let queries_coordinator_guard = self.queries_coordinator.lock();
        let queries_coordinator = unsafe { &mut *queries_coordinator_guard.deref().get() };

        match queries_coordinator.get_mut(query_id) {
            None => Err(ErrorCode::Internal("Query not exists.")),
            Some(query_coordinator) => {
                let query_ctx = query_coordinator
                    .info
                    .as_ref()
                    .expect("QueryInfo is none")
                    .query_ctx
                    .clone();

                query_coordinator.subscribe_fragment(&query_ctx, fragment_id, injector)
            }
        }
    }
}

struct QueryInfo {
    query_id: String,
    started: AtomicBool,
    current_executor: String,
    query_ctx: Arc<QueryContext>,
    remove_leak_query_worker: Option<JoinHandle<()>>,
    query_executor: Option<Arc<PipelineCompleteExecutor>>,
}

View on GitHub (pinned to 288d84d76e)