jdx/mise · error

Infinitive loop detected, all tasks are finished but the gra

Error message

Infinitive loop detected, all tasks are finished but the graph isn't empty {0} {1:#?}

What it means

A Windows-only panic (expect) inside ToolVersion::runtime_path at src/toolset/tool_version.rs:266. For non-locked tool requests with a runtime pathname, mise looks up installs_path/<runtime-name>; on Windows a runtime symlink may be a file whose content is the target. If that file is a runtime symlink (is_runtime_symlink), its target resolves (file::resolve_symlink), parent.join(target) is a directory (line 263 guard), but absolutize() then fails to canonicalize that existing directory, expect panics and takes down the process.

Source

Thrown at src/task/deps.rs:373

        for task in leaves {
            let key = task_key(&task);

            if self.sent.insert(key.clone()) {
                trace!("Scheduling task {0}", task.name);
                if let Err(e) = self.tx.send(Some(task)) {
                    trace!("Error sending task: {e:?}");
                    self.sent.remove(&key);
                }
            }
        }

        if self.is_empty() {
            trace!("All tasks finished");
            if let Err(e) = self.tx.send(None) {
                trace!("Error closing task stream: {e:?}");
            }
        } else if leaves_is_empty && self.sent.len() == self.removed.len() {
            panic!(
                "Infinitive loop detected, all tasks are finished but the graph isn't empty {0} {1:#?}",
                self.all().map(|t| t.name.clone()).join(", "),
                self.graph
            )
        }
    }

    /// listened to by `mise run` which gets a stream of tasks to run
    pub fn subscribe(&mut self) -> mpsc::UnboundedReceiver<Option<Task>> {
        let (tx, rx) = mpsc::unbounded_channel();
        self.tx = tx;
        self.emit_leaves();
        rx
    }

    pub fn is_empty(&self) -> bool {
        self.graph.node_count() == 0
    }

View on GitHub (pinned to 9dcfcaa0dc)

Solutions

  1. Delete the runtime shim file (e.g. ~/.local/share/mise/installs/<tool>/<runtime-name>, a plain file) and rerun mise so it recreates a consistent symlink
  2. Uninstall and reinstall the affected tool version to rebuild both install and runtime links atomically
  3. Enable LongPathsEnabled (HKLM\SYSTEM\CurrentControlSet\Control\FileSystem) or move MISE_DATA_DIR to a short root (C:\mise) to avoid MAX_PATH
  4. Run `mise doctor` to confirm the installs tree layout, and verify the shim file's stored target with `Get-Content` before deleting
  5. Update mise — later versions replace this expect with a propagated Result

Example fix

# before: panic at src/toolset/tool_version.rs:266
# message: failed to absolutize path
mise x python@3.12 -- python -V   # crashes while resolving runtime path

# after: remove the file-based runtime symlink shim and let mise rebuild it
Remove-Item "$env:USERPROFILE\.local\share\mise\installs\python\3.12" -Force   # plain shim file
mise install python@3.12
mise x python@3.12 -- python -V
Defensive patterns

Strategy: validation

Validate before calling

// Rust callers on Windows: validate a file-based runtime symlink shim end-to-end
fn usable_runtime_path(shim: &Path) -> Option<PathBuf> {
    let target = PathBuf::from(std::fs::read_to_string(shim).ok()?);
    let joined = shim.parent()?.join(target);
    let canon = std::fs::canonicalize(&joined).ok()?;
    canon.is_dir().then_some(canon)
}

Try / catch

Panic via expect() — not catchable as an error. Pre-validate the shim chain (read shim file -> join parent -> canonicalize -> is_dir) and treat failure as 'runtime symlink broken: delete shim and rerun mise install', optionally wrapping in catch_unwind at the process boundary.

Prevention

When it happens

Trigger: On Windows only: resolving runtime_path() (used by shims/exec to pick the active runtime dir) when the runtime-name entry is a file-based symlink shim, its recorded target points to an existing directory, and canonicalization of that directory fails — classic causes are paths exceeding MAX_PATH with long paths disabled, junction/symlink chains Windows cannot finalize, or ACLs denying traversal on a path component.

Common situations: Same class as the install_path panic: long nested profile paths with LongPathsEnabled off; runtime shim files left over after moving MISE_DATA_DIR or the installs tree; targets on network drives with flaky resolution; interrupted installs leaving a shim file whose target exists but is itself a dangling junction.

Related errors


AI-assisted analysis of jdx/mise@9dcfcaa0dc (2026-08-17). Data as JSON: /api/errors/86f3b205c90f8d60. Report an issue: GitHub.