jdx/mise · error

executor must be initialized before displaying cache stats

Error message

executor must be initialized before displaying cache stats

What it means

After a task run, mise prints cache hit/miss statistics from the executor's `cache_stats` mutex. This `.expect()` panics if `display_task_cache_stats` is called without an initialized executor. It is an invariant guard ensuring stats display only happens on code paths where tasks actually ran.

Solutions

  1. Report the panic with `MISE_DEBUG=1` output and the invoking command to the mise repo
  2. Guard the stats display so it is skipped when the run never reached executor setup
  3. Check upstream error handling: ensure setup failures propagate instead of falling through to display
  4. Rebuild/update mise to rule out a stale binary

Example fix

// before
let stats = *self.executor.as_ref().expect("executor must be initialized before displaying cache stats").cache_stats.lock().unwrap();
// after
let Some(executor) = self.executor.as_ref() else { return; };
let stats = *executor.cache_stats.lock().unwrap();
Defensive patterns

Strategy: validation

Validate before calling

# Only inspect cache stats after a successful run
mise run <task> && echo "run ok"  # stats printing is internal; never invoke display paths directly

Prevention

When it happens

Trigger: Calling `display_task_cache_stats()` after a run that failed before `setup_executor()`; invoking the method from a new code path (e.g. a stats subcommand) that never created the executor; an executor-initialization error being swallowed upstream.

Common situations: Developer adds cache-stats output to a new CLI path; an aborted run (e.g. tool install failure) still reaches the stats display in modified code.

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 jdx/mise@afd2eddd3a (2026-09-09). Data as JSON: /api/errors/75a010959d3fea09. Report an issue: GitHub.

Appendix: source

Thrown at src/cli/run.rs:1439

            } else {
                bail!(
                    "`{dp}` is not executable. {}",
                    file::make_executable_hint(path)
                )
            }
        }
        Ok(())
    }

    fn timings(&self) -> bool {
        !self.quiet(None) && !self.no_timings
    }

    fn display_task_cache_stats(&self) {
        let stats = *self
            .executor
            .as_ref()
            .expect("executor must be initialized before displaying cache stats")
            .cache_stats
            .lock()
            .unwrap();
        let lookups = stats.hits.saturating_add(stats.misses);
        if lookups == 0 {
            safe_eprintln!("Task cache: no lookups");
            return;
        }
        let hit_rate = stats.hits.saturating_mul(100) / lookups;
        safe_eprintln!(
            "Task cache: {}/{} hits ({}%), {} restored, {} saved",
            stats.hits,
            lookups,
            hit_rate,
            ByteSize::b(stats.restored_bytes).display().iec(),
            crate::ui::time::format_duration(stats.time_saved),
        );
    }

View on GitHub (pinned to afd2eddd3a)