databendlabs/databend · error

ExecutorTask::None => unreachable!()

Error message

ExecutorTask::None => unreachable!()

What it means

This is a Rust `unreachable!()` panic in `QueriesExecutorTasks::push_task`. The `ExecutorTask` enum has a `None` variant used as a placeholder/empty state, and the executor's internal invariant is that only real tasks (Sync, Async, AsyncCompleted) are ever pushed onto a worker's queue. Pushing `ExecutorTask::None` indicates an executor bookkeeping bug.

Solutions

  1. Inspect the caller of `push_task` to find where an `ExecutorTask::None` was produced instead of a real task
  2. Guard call sites with `if !matches!(task, ExecutorTask::None)` before pushing, or return a proper error instead of panicking
  3. Reproduce with the failing query and enable executor debug logs (trace!) to trace which scheduling step emitted the None task
  4. Check for recent regressions in the queries executor refactor in src/query/service/src/pipelines/executor/

Example fix

// before
match task {
    ExecutorTask::None => unreachable!(),
    ExecutorTask::Sync(p) => sync_queue.push_back(p),
    ...
}
// after
match task {
    ExecutorTask::None => return Err(ErrorCode::Internal("push_task called with ExecutorTask::None")),
    ExecutorTask::Sync(p) => sync_queue.push_back(p),
    ...
}
Defensive patterns

Strategy: type-guard

Validate before calling

if matches!(task, ExecutorTask::None) { return Err(ErrorCode::Internal("task is ExecutorTask::None")); }

Type guard

fn is_real_task(t: &ExecutorTask) -> bool { !matches!(t, ExecutorTask::None) }

Prevention

When it happens

Trigger: Calling `push_task` with an `ExecutorTask::None` value, which should only happen if the executor's scheduling logic built or forwarded a placeholder task instead of an actual processor/completion notification.

Common situations: Custom pipeline/executor modifications in the Databend query engine, or a bug in task scheduling where a slot initialized as `None` is pushed without being replaced by a real task.

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

Appendix: source

Thrown at src/query/service/src/pipelines/executor/queries_executor_tasks.rs:364

            }
        }

        ExecutorTask::None
    }

    pub fn push_task(&mut self, worker_id: usize, task: ExecutorTask) {
        self.tasks_size += 1;
        debug_assert!(
            worker_id < self.workers_sync_tasks.len(),
            "out of index, {}, {}",
            worker_id,
            self.workers_sync_tasks.len()
        );
        let sync_queue = &mut self.workers_sync_tasks[worker_id];
        let completed_queue = &mut self.workers_completed_async_tasks[worker_id];
        let async_queue = &mut self.workers_async_tasks[worker_id];
        match task {
            ExecutorTask::None => unreachable!(),
            ExecutorTask::Sync(processor) => sync_queue.push_back(processor),
            ExecutorTask::Async(processor) => async_queue.push_back(processor),
            ExecutorTask::AsyncCompleted(task) => completed_queue.push_back(task),
        }
    }
}

View on GitHub (pinned to 288d84d76e)