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
- Run `pitchfork supervisor status --json` manually and inspect the JSON; compare against pitchfork 2.25.0+ output.
- Upgrade or align pitchfork to the version mise expects (2.25.0+) so the status schema matches.
- Restart the pitchfork supervisor (`pitchfork supervisor restart`) and retry the mise command.
- 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
- Use a pitchfork version known to work with your mise version (2.25.0+)
- Run `pitchfork supervisor status --json` manually after pitchfork upgrades to spot schema changes
- Keep pitchfork and mise updated together
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
- cached is not canonical JSON
- deps output rules should serialize
- local action result is invalid
- mas list --json returned no parseable app objects
- mise daemons selects project daemon names; use pitchfork…
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)