jdx/mise · error
task executor initialized
Error message
task executor initialized
What it means
This panic is an internal invariant check in mise's task runner. After tool installation completes, `setup_executor()` must have populated `self.executor`; `parallelize_tasks` then unwraps it to run preflight validation on every scheduled task. If the executor is `None` at this point, a refactoring or ordering bug in the run pipeline has occurred — users cannot trigger it via normal CLI input.
Solutions
- Re-run the same mise command with `MISE_DEBUG=1` to capture the stack trace and file a mise bug report with the command and trace
- Check that no local mise wrapper, shim, or patched build is running stale or modified code; rebuild with `mise run build`
- Inspect `setup_executor()` in src/cli/run.rs to confirm it assigns `self.executor` on every success path
- Upgrade to the latest mise release in case this was a regression already fixed upstream
Example fix
// before
let executor = self.executor.as_ref().expect("task executor initialized");
// after
let Some(executor) = self.executor.as_ref() else {
bail!("internal error: task executor was not initialized; please report this bug");
}; Defensive patterns
Strategy: validation
Validate before calling
if std::env::var("MISE_DEBUG").is_ok() { eprintln!("repro: mise run <task>"); }
// For plugin/CI authors: assert the binary is unmodified
// cargo build && target/debug/mise run <task> # compare against released mise Try / catch
// Panic, not Result: catch it only to improve the report
let output = std::process::Command::new("mise").args(["run", "build"]).output()?;
if !output.status.success() && String::from_utf8_lossy(&output.stderr).contains("task executor initialized") {
eprintln!("mise internal bug — file an issue with MISE_DEBUG=1 output");
} Prevention
- Never bypass the standard `mise run` pipeline with custom entry points
- Keep executor setup and use in the same command implementation
- Report any occurrence with a debug trace; it always indicates a mise bug
When it happens
Trigger: Only reachable if `setup_executor()` silently succeeds without setting `self.executor`, or if code is reordered so `parallelize_tasks` runs before `setup_executor()`. Also triggered if a developer bypasses the standard `run` pipeline (e.g. a new entry point calling `parallelize_tasks` directly).
Common situations: Seen during development of mise itself: someone adds a code path that returns early from setup with `Ok(())` while skipping executor assignment, or a contributor moves the preflight loop before executor creation.
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
- executor must be initialized before running tasks
- artifact directory was initialized
- command wait must complete
- executor must be initialized before displaying cache stats
- generated mise usage spec
AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09).
Data as JSON: /api/errors/508ed8f41defbe5f.
Report an issue: GitHub.
Appendix: source
Thrown at src/cli/run.rs:902
let tasks = self.prepare_tasks(&config, tasks).await?;
let num_tasks = tasks.all().count();
// Step 2: Setup output handler and validate tasks
self.setup_output_and_validate(&tasks)?;
self.output = Some(self.output(None));
// Step 3: Install tools needed by tasks
if !self.skip_tools {
self.install_task_tools(&mut config, &tasks, &previewed_tools)
.await?;
}
// Step 4: Create TaskExecutor after tool installation
self.setup_executor()?;
// Validate every scheduled invocation before starting the scheduler so
// an invalid parent or dependency cannot run any task commands first.
let executor = self.executor.as_ref().expect("task executor initialized");
for task in tasks.all() {
executor
.preflight_task_usage(&config, task)
.await
.wrap_err_with(|| format!("failed to validate task {}", task.name))?;
}
// Disable exit-on-ctrl-c so tasks can handle SIGINT gracefully
ctrlc::exit_on_ctrl_c(false);
let timer = std::time::Instant::now();
let this = Arc::new(self);
let config = config.clone();
// Step 5: Initialize scheduler and run tasks
let mut scheduler = crate::task::task_scheduler::Scheduler::new(this.jobs());
let main_deps = Arc::new(Mutex::new(tasks));
View on GitHub (pinned to afd2eddd3a)