This release fixes a trust bypass: an untrusted path: tool version could put a directory on PATH. It also adds several bootstrap features: apt repositories and PPAs, macOS login items, rpm-ostree layering on Fedora Atomic, and run0/doas support. Beyond that, it improves mise dot status, adds GitHub OAuth conveniences, and fixes problems across npm, prune, brew and dotfiles sync.
Security
path:tool versions now require trust. Before, an untrusted repository could shipnode path:./localin.tool-versionsormise.toml.mise activatewould then put./local/binahead of yourPATHon the nextcd, without asking for trust, so alocal/bin/gitthere would run in place of your realgit. Configs with apath:version are now skipped until trusted, and you see the usualis not trusted, run mise trustwarning. Aftermise trust,path:works as before. Other version forms are unaffected. Reported by Anthropic and Ada Logics. #14358mise bootstrap --adoptnow rejects repository URLs that embed credentials (auser:TOKEN@part). It used to quietly fall back to a plain clone, which left the token in.git/config. Use a Git credential helper or SSH agent. #14315- Download file names decoded from URLs (for example
tool%2F..%2Fpwned.tar.gz, orC:names on Windows) can no longer point outside the download directory. Ordinary escapes such as%20still decode. #14274 (@JamBalaya56562, @hktitof)
Added
Bootstrap
-
[bootstrap.apt.sources]declares PPAs and vendor apt repositories next to the packages that come from them. You no longer need apre-packageshook that runsadd-apt-repository. Each source is written as a deb822 file at/etc/apt/sources.list.d/mise-<name>.sources. Its signing key is fetched, trimmed to the fingerprints you declared, and stored inline in that file, so deleting the file removes both the repository and its key. PPAs need onlyppa = "owner/name"and are added only on Ubuntu and Ubuntu-based distros, so the same config also works on Debian. Other repositories needuris,keyandfingerprint;suitesandcomponentsare optional. An unpinnedapt:package that is installed from the distro is moved to the declared source. Inline keys require apt 2.4 or later (Ubuntu 22.04, Debian 12). #14306, #14348[bootstrap.apt.sources] git-core = { ppa = "git-core/ppa" } fish = { ppa = "fish-shell/release-4" } [bootstrap.packages] "apt:git" = "latest" "apt:fish" = "latest"
-
macOS login items.
[bootstrap.macos.login_items]declares the apps listed under "Open at Login".statusandplanreport missing apps, andmise bootstrapadds them. The list is additive by default, so apps that register themselves are left alone. Setexclusive = trueto have the config own the whole list. #14354[bootstrap.macos.login_items] apps = ["/Applications/Ghostty.app", "~/Applications/Example.app"]
-
Fedora Atomic hosts. On ostree-booted hosts (Silverblue, Bazzite, secureblue, ...),
dnf:installs now stop with an explanation instead of failing inside dnf on read-only/usr. To layer packages instead, setsystem_packages.ostree = "layer". mise then runs onerpm-ostree installfor the whole batch and reports layered packages aspending rebootuntil you reboot. Version pins are skipped, andupgradepoints you torpm-ostree upgrade. #14353, #14357 -
run0anddoasfor privilege elevation. On hosts withoutsudo, mise uses the first ofsudo,run0ordoasit finds onPATH. To always use a specific one, setsystem_packages.elevate_with(orMISE_SYSTEM_PACKAGES_ELEVATE_WITH), for example"run0". #14351 -
dnf package groups. Entries such as
"dnf:@development-tools" = "latest"are now installed, upgraded and checked as groups. Before,statusalways reported them as missing. Environment groups (@^name) are not supported. #14347 -
Templated
[bootstrap.repos]paths. Repo keys can use templates, so each machine can choose its own clone location with a var answered once throughmise vars prompt. Unanswered vars use theirdefault. #14359[vars.repos_dir] default = "~/src" prompt = "Where should repositories be cloned?" [bootstrap.repos] "{{ vars.repos_dir }}/project-a" = { url = "git@github.com:example/project-a.git" }
Tools and backends
libc()andavx2()template functions forhttp:URLs. They let one entry pick-musland no-AVX2-baselinebuilds: append{{ avx2(yes="", no="-baseline") }}{{ libc(gnu="", musl="-musl") }}to theurltemplate after{{ os() }}-{{ arch() }}.mise lockrecords every variant. #14298- PyPI Simple indexes: when
pypi.registry_urlis not a/jsonURL, mise now asks for the PEP 691 JSON format. If the index supports it, upload times come from the index, sominimum_release_agenow works with private indexes. HTML-only indexes behave as before. #14352 - Rust mirrors: when
RUSTUP_UPDATE_ROOTis set,rustup-initis downloaded from{root}/dist/<host-triple>/rustup-initinstead ofsh.rustup.rs. This lets mirrors such as panamax serve the first download too. mise also forwardsRUSTUP_DIST_SERVERandRUSTUP_UPDATE_ROOTfrom config env to rustup. #14356
GitHub OAuth
-
github.oauth_copy_codecopies the one-time device code to the clipboard duringmise token github --oauth, likegh auth login --clipboard. When the setting is unset, mise asks in an interactive terminal. Only the device code is copied, never the token. #14269 -
github.oauth_cache_getandgithub.oauth_cache_setkeep the long-lived refresh token in a password manager or keychain, so the plaintext cache file holds only the 8-hour access token. Both settings must be set and can only go in global config. An existing cached refresh token moves into the store at the next refresh. If the store can't be read, mise keeps the cached token. If it can't be written, mise warns and keeps the token in the file. #14360[settings.github] oauth_cache_get = "pass show mise/github-oauth" oauth_cache_set = "pass insert -m -f mise/github-oauth"
Dotfiles and skills
mise dot statusoutput is grouped into sections: Tracking, Repository, Conflicts, Automatic capture and Bootstrap, followed by a "Next steps" list of commands. The table now lists only entries that need attention and counts the rest. Use--verbose/-vto list every entry.--jsonand--missingare unchanged. #14361mise dot statusnow shows tracked entries whose variants don't match this machine asnot on this machine (variants: work), instead of plaintracked. In--json,statestaystrackedand areasonfield is added. #14266mise skills syncnow lists the skill links it creates, plus.mise-skills.json, in the repository's.git/info/exclude, so they stay out ofgit status. Your hand-written skills are unaffected, and nothing in the repository itself changes. #14374
Changed
- Registry:
opencodenow installs OpenCode 2 from npm (npm:@opencode/cli).opencode@latestmoves to v2 on your next upgrade.opencode@1keeps v1 from aqua. #14295 - Go: if
go.modorgo.workhas an exactgo X.Y.Zline and notoolchainline, mise now uses it as the toolchain version and no longer shows the deprecation warning. This matches how Go reads the file. The old advice to add atoolchainline didn't work, becausego mod tidyremoves it.go X.Ylines without a patch version are still deprecated. #14308 - The official
-debianDocker image now includeslibatomic1, so Node.js 26 installs and runs without extra steps. #14303
Fixed
Tools, shims and updates
auto_updatenow updates only tools that are already installed. Since 2026.10.7, the first shell prompt could install every lazy tool declared withauto_update. #14368 (@ryanrhughes)- Downloads started by
mise exec,mise xand shims now retry up tohttp_retries, likemise install. Before, they made a single attempt. Remote version lookups still make one attempt, so shims don't get slower. #14342 - npm tools installed from a lockfile in one project no longer show up as missing, or as
<version>~aube~<digest>, in another config that requestslatestor a version prefix without a lockfile. Withinstall_layout = "identity", unlocked requests get their own plain install, separate from the project's lockfile-built one. The same applies to uv-locked pipx tools. #14307, #14309 mise pruneno longer removes tool versions used only by inline tasktools. It also keeps a uv-lockedpipx:/pypi:tool's installs for every Python version, not just the one in the current directory. #14334, #14335- Running reshim in one project no longer deletes
[wrappers]command wrappers defined in other projects. #14355 - With
skills.auto_sync,mise upgradenow relinks agent skills to the new version. Before, the links kept pointing at the replaced install, whichprunecould then delete. #14373 - Remote tasks no longer break commits when they are fetched from a git hook. Their clone was writing over the commit's index (
GIT_INDEX_FILE). Fixed by updating gix to 0.89. #14316 (@any-victor) - Packslip tools whose signing workflow moved, such as aube moving from
release-plz.ymltorelease.yml, now upgrade when both workflows are in theworkflowlist.mise lockalso keeps the signer of a renamed or transferred project. #14338, #14362 - aqua packages that have no repo now print the "cannot list versions" warning once, and it tells you to pin an exact version. #14336
- On Windows, the
tool-updateservice no longer opens a console window that stops the updater when you close it. #14344
Homebrew and system packages
- Brew bottles now install their
etc/varfiles and run the formula'spost_install_steps. For example,openssl@4now gets its CA bundle andopenssl.cnf. Existing files are kept, and the bottle's copy is saved next to them as.default. Protectedcopysteps (overwrite: false) are respected. #14272, #14311 - On Linux, Homebrew
uses_from_macosdependencies are now installed. This fixes runtime errors such aslibbz2.so.1.0missing forbrew:chafa. #14288 (@itskyf) mise bootstrapno longer runschownon a Homebrew prefix owned by another non-root user. It stops with an explanation instead. #14345- Casks that mise evaluates itself now support the
generate_completions_from_executablestanza. #14255 (@pmmmwh) mise oci buildno longer runs the host's apt hooks against the image. Those hooks broke non-root builds that install packages such ascmake. #14296- When elevation is unavailable, mise no longer tells you to run privileged helpers that read their plan from stdin, because they can't run on their own. It now tells you to re-run the mise command as root. #14350
Dotfiles
- When another machine had saved a profile-variant file while that profile was inactive here, turning the profile on no longer publishes a deletion or reverts the shared file. Status reports it as
not applied here, andmise dot pullapplies it, or stops with a conflict that you resolve with--take-remoteor--keep-local. #14275 - After
mise bootstrap --adopt, unchanged encrypted files reuse the ciphertext already in history. Before, they were re-encrypted, andmise dot syncpaused on a conflict. #14300 - When
/homeis a symlink (Fedora Atomic), adopting now restoresconfig/entries, andmise dot origin setno longer shows a false "Not portable" warning. #14315 mise dot applyapplies entries that write mise's own config first, then plans everything else from the new config. A newly added entry now takes effect in a single run. #14339mise dot diffnow shows per-file hunks, missing files and type mismatches for directory copy entries. #14333
Schema
- The JSON schema now accepts
[bootstrap.secrets],[bootstrap.groups],[bootstrap.users], and table forms ofvars._.fileandvars._.source. Editors and linters such as tombi and Taplo no longer flag configs that mise accepts. #14322, #14340, #14383 (@JamBalaya56562, @risu729)
Documentation
- New guidance on when to use
mise bootstrap --fromversus--adopt, whyfish = "auto"is recommended for fish activation, when to usemise dot sync,pullandapply, and how to check from a shim whether a tool is installed. #14301, #14304, #14343, #14337
Upgrade notes
- If an untrusted project uses a
path:tool version, runmise trustin it. - Scripts that parse the default table from
mise dot statusshould add--verboseor switch to--json. opencode@latestmoves to OpenCode 2. Pinopencode@1to stay on v1.mise bootstrap --adoptwith a URL that contains credentials now fails. Use a credential helper or SSH agent instead.
Registry
- New aqua packages:
Alice39s/xmtr,bufbuild/protoschema-plugins/protoc-gen-jsonschemaandtakumin/qemu-bin.
New Contributors
Full Changelog: v2026.10.8...v2026.10.9
💚 Sponsor mise
mise is built and maintained by @jdx, an open source developer at entire.io, the title sponsor of his open source work.
If mise saves you or your team time, please consider becoming an individual or company sponsor. Your support funds ongoing development and helps keep mise fast, free, and independent.