jdx/mise · error

pitchfork supervisor is not running; run mise daemons start

Error message

pitchfork supervisor is not running; run mise daemons start

What it means

Before opening the TUI dashboard, `mise daemons tui` verifies that the pitchfork supervisor process is up via `runtime.supervisor_up(root)`. If the supervisor isn't running there is no runtime to attach the dashboard to, so mise bails and tells the user to start it.

Solutions

  1. Run `mise daemons start` in the project to bring up the pitchfork supervisor.
  2. Re-run `mise daemons tui` after confirming `mise daemons status` works.
  3. Check pitchfork state/logs if `start` claims success but the supervisor immediately dies.

Example fix

// before
$ mise daemons tui   // "pitchfork supervisor is not running"
// after
$ mise daemons start
$ mise daemons tui
Defensive patterns

Strategy: validation

Validate before calling

mise daemons status >/dev/null 2>&1 || mise daemons start

Prevention

When it happens

Trigger: Run `mise daemons tui` inside a project with a valid root while no pitchfork supervisor has been started for that root (no prior `mise daemons start` / supervisor not reachable).

Common situations: New shell or machine reboot where the supervisor died; first-time user running `tui` before ever running `mise daemons start`; supervisor crashed and wasn't restarted.

Understand the failure class

Background: "not installed", "pip install", "required for": how missing-dependency errors surface across open-source libraries — this error's family across 34 libraries.

Related errors


AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17). Data as JSON: /api/errors/4e7ba28a1d86dbea. Report an issue: GitHub.

Appendix: source

Thrown at src/cli/daemons.rs:108

            Some(Commands::Tui(args)) => ("tui", args.args, false),
            Some(Commands::Ls(list)) => ("ls", vec![], list.json),
            None => ("ls", vec![], self.list.json),
        };
        let config = Config::get().await?;
        let root = config
            .project_root
            .as_deref()
            .ok_or_else(|| eyre::eyre!("mise daemons requires a project configuration"))?;
        // The dashboard is global to the supervisor, not one invocation per daemon root.
        if action == "tui" {
            if args.first().is_some_and(|arg| !arg.starts_with('-')) {
                bail!("mise daemons tui opens the dashboard; pass TUI flags, not daemon names");
            }
            let previous = runtime::read_state(root)?;
            let (config, ts) = runtime::toolset(&config, false).await?;
            let runtime = Runtime::from_toolset(&config, &ts, Some(&previous.bin)).await?;
            if !runtime.supervisor_up(root).await? {
                bail!("pitchfork supervisor is not running; run mise daemons start");
            }
            return runtime
                .exec(root, [vec!["tui".into()], args].concat())
                .await;
        }
        let loaded = config.daemons()?;
        let mut roots = loaded.roots();
        if !roots.iter().any(|r| r == root) {
            roots.push(root.to_path_buf());
        }
        let (names, flags) = split_args(action, &args)?;
        let install = matches!(action, "start" | "restart");
        let mut root_ids = Vec::new();
        for root in &roots {
            let previous = runtime::read_state(root)?;
            let namespace = if previous.namespace.is_empty() {
                runtime::namespace(root)?
            } else {

View on GitHub (pinned to 533346cc37)