jdx/mise · error

another daemon profile is active for

Error message

another daemon profile is active for {}; stop its daemons and leave its shell sessions before switching MISE_ENV

What it means

mise records which MISE_ENV profile owns a project's daemon state. During daemon prepare, if saved state shows a different profile and at least one of that profile's daemons (or its pitchfork sessions) is still active, mise refuses to proceed to avoid two profiles fighting over the same daemon namespace. The user must stop the old profile's daemons and close its shell sessions before switching MISE_ENV.

Solutions

  1. Stop the daemons belonging to the old profile: switch MISE_ENV back and run `mise daemons stop` (or `pitchfork stop` for the project).
  2. Close leftover shell sessions started under the previous MISE_ENV so pitchfork's liveness no longer reports them.
  3. If the state is truly stale, remove the project's daemon state directory after confirming nothing is running, then retry.
  4. Verify with `pitchfork supervisor status --json` and `pitchfork project list --json` that nothing for this root is live before switching.

Example fix

// before
MISE_ENV=production mise daemons start   # daemons still running under staging

// after
MISE_ENV=staging mise daemons stop       # stop old profile first
MISE_ENV=production mise daemons start
Defensive patterns

Strategy: try-catch

Validate before calling

# Before switching MISE_ENV, ensure no daemons from the old profile are live
MISE_ENV=$OLD_ENV pitchfork project list --json | jq -e '.[] | select(.directory=="'$PWD'" and .liveness_status!="dead")' \
  && echo "stop old-profile daemons first" || echo "safe to switch"

Try / catch

try {
  await mise.daemons.start();
} catch (e) {
  if (String(e).includes("another daemon profile is active")) {
    console.error("Stop the previous MISE_ENV profile's daemons and close its shells, then retry.");
  }
}

Prevention

When it happens

Trigger: Calling prepare (via emit) where read_state(root) returns a previous state with a non-empty namespace, previous.profile != current MISE_ENV, and active(root, previous) finds a daemon in running/waiting/stopping state or a live pitchfork session for this root.

Common situations: Switching `MISE_ENV=staging` to `MISE_ENV=production` (or unsetting it) in a project that still has daemons started under the previous environment, with old shell sessions or a supervisor still holding them.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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

Appendix: source

Thrown at src/daemons/runtime.rs:210

            }
        }
        Ok(false)
    }

    pub(crate) async fn prepare(
        &self,
        root: &Path,
        set: &DaemonSet,
        force_registration: bool,
    ) -> Result<(State, fslock::LockFile)> {
        let lock = crate::lock_file::LockFile::at(&state_dir(root).join("project.lock")).lock()?;
        let previous = read_state(root)?;
        let profile = crate::env::MISE_ENV.clone();
        if !previous.namespace.is_empty()
            && previous.profile != profile
            && self.active(root, &previous).await?
        {
            bail!(
                "another daemon profile is active for {}; stop its daemons and leave its shell sessions before switching MISE_ENV",
                root.display()
            );
        }
        let namespace = if !previous.namespace.is_empty() {
            previous.namespace.clone()
        } else {
            namespace(root)?
        };
        let mut state = State {
            root: root.into(),
            profile,
            namespace,
            ids: previous.ids,
            bin: self.bin.clone(),
            config_hash: String::new(),
        };
        for daemon in set.daemons.values() {

View on GitHub (pinned to 533346cc37)