v2026.2.20

jdx/misev2026.2.20Feb 25, 2026by mise-en-dev

AI Summary

A feature-packed release that replaces the conda backend with production-grade internals, adds a native .NET SDK plugin, and finally enforces per-task timeouts. Several lockfile and environment-handling fixes round things out.

Key Highlights

  • Conda backend rewritten with rattler crates
  • Native .NET SDK management with side-by-side versions
  • Per-task timeouts are now enforced with SIGTERM and grace period
  • VSIX archive support for VS Code extensions
  • Registry: oxfmt formatter added

New Features

  • Conda backend rewrite using rattler (SAT-based solver, binary prefix replacement)
  • Core .NET SDK plugin with global.json support
  • Per-task timeout enforcement
  • VSIX archive support via HTTP backend
  • oxfmt registry entry
  • Lockfile not modified with --locked
  • Orphan lockfile entries pruning
  • Contradictory lockfile config error handling

Full Release Notes

A feature-packed release that replaces the conda backend with production-grade internals, adds a native .NET SDK plugin, and finally enforces per-task timeouts. Several lockfile and environment-handling fixes round things out.

## Highlights

- **Conda backend rewritten with rattler** -- The experimental conda backend has been completely rewritten to use the [rattler](https://github.com/conda/rattler) Rust crates (the same engine behind pixi), replacing ~1,600 lines of custom code that relied on the unsupported anaconda.org API. This brings a proper SAT-based dependency solver, correct binary prefix replacement, and repodata caching via CDN. [#8325](https://github.com/jdx/mise/pull/8325) by @jdx

- **Native .NET SDK management** -- A new core plugin for .NET SDK installs all versions side-by-side under a shared `DOTNET_ROOT`, matching .NET's native multi-version model. It uses Microsoft's official `dotnet-install` script and supports `global.json` for per-project SDK pinning. [#8326](https://github.com/jdx/mise/pull/8326) by @jdx

- **Per-task timeouts are now enforced** -- The `timeout` field on tasks (added in v2025.1.6 but never wired up) now actually kills tasks that exceed their limit. Timeouts send SIGTERM with a 5-second grace period before SIGKILL, and both per-task and global `task_timeout` settings are respected. [#8250](https://github.com/jdx/mise/pull/8250) by @tvararu

## Added

- **Core .NET SDK plugin** -- `mise use dotnet@8` now installs via a native core plugin with side-by-side version support and `global.json` detection. Configure `DOTNET_ROOT` via the new `dotnet.dotnet_root` setting. [#8326](https://github.com/jdx/mise/pull/8326) by @jdx
- **Per-task timeout enforcement** -- Tasks with a `timeout` field are now killed if they exceed the configured duration. Works with both per-task config and the global `task_timeout`/`--timeout` flag. [#8250](https://github.com/jdx/mise/pull/8250) by @tvararu
  ```toml
  [tasks.deploy]
  run = "npm run deploy"
  timeout = "5m"
  ```
- **VSIX archive support** -- The HTTP backend now recognizes `.vsix` files as ZIP archives and extracts them correctly, enabling tools distributed as VS Code extensions to be installed via `http:` URLs. [#8306](https://github.com/jdx/mise/pull/8306) by @sosumappu
- **Registry: `oxfmt`** -- Added the oxfmt formatter to the tool registry. [#8316](https://github.com/jdx/mise/pull/8316) by @taoufik07

## Changed

- **Conda backend rewritten with rattler crates** -- Replaces custom version matching, dependency resolution, archive extraction, and binary patching with the battle-tested rattler ecosystem (`rattler_solve`, `rattler_repodata_gateway`, `rattler::install`). Binary prefix replacement now works correctly (the old code skipped binary files entirely). Since the conda backend is still experimental, this is a non-breaking change. [#8325](https://github.com/jdx/mise/pull/8325) by @jdx

## Fixed

- **Lockfile not modified with `--locked`** -- `mise install --locked` no longer writes to `mise.lock`, matching the semantics of `cargo install --locked` and `uv pip install --locked`. [#8308](https://github.com/jdx/mise/pull/8308) by @jdx
- **Orphan lockfile entries pruned** -- `mise lock` now removes stale tool entries that are no longer present in config, keeping the lockfile aligned with the current toolset. [#8265](https://github.com/jdx/mise/pull/8265) by @mackwic
- **Contradictory lockfile config caught early** -- Setting `locked=true` alongside `lockfile=false` now produces a clear error instead of silently ignoring the lock. [#8329](https://github.com/jdx/mise/pull/8329) by @jdx
- **`watch_files` triggers on every change** -- The hook-env fast-path now checks `[[watch_files]]` paths, fixing a bug where only the first file change triggered the associated run command. [#8317](https://github.com/jdx/mise/pull/8317) by @jdx
- **Fish alias completions cleaned up** -- Setting or unsetting shell aliases in fish now clears stale completions, preventing tab-complete from offering outdated suggestions. [#8324](https://github.com/jdx/mise/pull/8324) by @jdx
- **JSON schema accepts age-encrypted env values** -- Fixed a `oneOf` ambiguity in the mise schema that rejected `[env]` entries using age encryption. [#8328](https://github.com/jdx/mise/pull/8328) by @adamliang0
- **Regal registry updated** -- The regal tool now points to its new home at `open-policy-agent/regal`. [#8315](https://github.com/jdx/mise/pull/8315) by @charlieegan3
- **Conda: locked installs preserve package data** -- `conda_packages` entries are no longer silently dropped during `--locked` installs, and concurrent downloads no longer race on the same temp file. [#8335](https://github.com/jdx/mise/pull/8335) by @jdx
- **Conda: solver no longer fails on Linux** -- Deduplicated repodata records before passing them to the solver, fixing "duplicate records" errors when installing tools like imagemagick. [#8337](https://github.com/jdx/mise/pull/8337) by @jdx

## New Contributors

- @tvararu made their first contribution in [#8250](https://github.com/jdx/mise/pull/8250)
- @sosumappu made their first contribution in [#8306](https://github.com/jdx/mise/pull/8306)
- @charlieegan3 made their first contribution in [#8315](https://github.com/jdx/mise/pull/8315)
- @taoufik07 made their first contribution in [#8316](https://github.com/jdx/mise/pull/8316)
- @adamliang0 made their first contribution in [#8328](https://github.com/jdx/mise/pull/8328)
- @mackwic made their first contribution in [#8265](https://github.com/jdx/mise/pull/8265)

**Full Changelog**: https://github.com/jdx/mise/compare/v2026.2.19...v2026.2.20