jdx/mise · error

cannot establish pitchfork supervisor status

Error message

cannot establish pitchfork supervisor status: {status}

What it means

mise determines whether the pitchfork supervisor is running by parsing `pitchfork supervisor status --json` and expecting a top-level "status" string of exactly "up" or "down". Any other shape — missing field, null, unexpected value — is unrecoverable for mise's logic, so it bails including the raw JSON. This indicates an unexpected pitchfork response rather than a user mistake.

Solutions

  1. Run `pitchfork supervisor status --json` manually and inspect the JSON; compare against pitchfork 2.25.0+ output.
  2. Upgrade or align pitchfork to the version mise expects (2.25.0+) so the status schema matches.
  3. Restart the pitchfork supervisor (`pitchfork supervisor restart`) and retry the mise command.
  4. Report the raw JSON from the error to mise/pitchfork if the schema looks correct — it may be a parsing bug.
Defensive patterns

Strategy: try-catch

Validate before calling

// Check the supervisor status shape before relying on it
const raw = execSync('pitchfork supervisor status --json').toString();
const s = JSON.parse(raw);
if (!['up','down'].includes(s?.status)) console.warn('unexpected supervisor status payload:', raw);

Type guard

function hasKnownStatus(v) {
  return v && typeof v.status === "string" && ["up", "down"].includes(v.status);
}

Try / catch

try {
  await mise.daemons.start();
} catch (e) {
  if (String(e).includes("cannot establish pitchfork supervisor status")) {
    console.error("Pitchfork JSON schema mismatch — align pitchfork version with mise's expectation.");
  }
}

Prevention

When it happens

Trigger: supervisor_up (via active/prepare) receives JSON from `pitchfork supervisor status --json` whose status["status"].as_str() is neither Some("up") nor Some("down") — e.g. a changed schema in a newer/older pitchfork, an error object, or a partial JSON payload.

Common situations: A pitchfork version whose supervisor status JSON schema differs from what mise expects, a corrupted or truncated pitchfork response, or pitchfork emitting a JSON error object because the supervisor is in a broken state.

Related errors


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

Appendix: source

Thrown at src/daemons/runtime.rs:164

    pub(crate) async fn status(&self, root: &Path, id: &str) -> Result<serde_json::Value> {
        let out = self
            .output(root, &["status".into(), id.into(), "--json".into()])
            .await?;
        Ok(serde_json::from_str(&out)?)
    }

    pub(crate) async fn supervisor_up(&self, root: &Path) -> Result<bool> {
        let out = self
            .output(
                root,
                &["supervisor".into(), "status".into(), "--json".into()],
            )
            .await?;
        let status: serde_json::Value = serde_json::from_str(&out)?;
        match status["status"].as_str() {
            Some("up") => Ok(true),
            Some("down") => Ok(false),
            _ => bail!("cannot establish pitchfork supervisor status: {status}"),
        }
    }

    async fn active(&self, root: &Path, state: &State) -> Result<bool> {
        for id in &state.ids {
            if let Ok(value) = self.status(root, id).await
                && matches!(
                    value["status"].as_str(),
                    Some("running" | "waiting" | "stopping")
                )
            {
                return Ok(true);
            }
        }
        if self.supervisor_up(root).await? {
            let sessions: Vec<serde_json::Value> = serde_json::from_str(
                &self
                    .output(root, &["project".into(), "list".into(), "--json".into()])

View on GitHub (pinned to 533346cc37)