Skip to content

chore(deps): update dependency jdx/mise to v2026 - #220

Open
renovate[bot] wants to merge 1 commit into
scipfrom
renovate/jdx-mise-2026.x
Open

renovate[bot] wants to merge 1 commit into
scipfrom
renovate/jdx-mise-2026.x

Conversation

@renovate

@renovate renovate Bot commented Jul 20, 2026 •

Copy link
Copy Markdown
Contributor

Note

This PR body was truncated due to platform limits.

This PR contains the following updates:

Package Type Update New value References Sourcegraph
jdx/mise uses-with major 2026.10.19 source code search for "jdx/mise"

Test plan: CI should pass with updated dependencies. No review required: this is an automated dependency update PR.


Release Notes

jdx/mise

v2026.10.19: : Security hardening across trust, installs and provenance; lockfiles now rebuilt completely by default

Compare Source

Most of this release closes ways an untrusted repository, download host or mirror could run code, leak credentials or get around verification. Some of these fixes make mise stricter, so check Breaking Changes before you upgrade. Also in this release: lockfile_mode = "generate" is now the default, mise lsp sends semantic highlighting, and there is a new {{ mise_config_dir }} template variable.

Highlights
  • Trust is narrower and tied to the files you trusted. Help output, shims, hooks, config writes and shell completion no longer trust a project or run its code without your consent. Trust also follows worktrees, symlinks and config directories correctly, and safe mode closes several more gaps.
  • Verification fails closed. Pinned checksums, Node signatures, SLSA provenance (including the tag it was built from) and GitHub attestations are now enforced. Before, a 404 or a missing file could make mise skip them.
  • Hostile inputs are contained. Archives, asset names, versions, lockfiles and HTTP responses can no longer write outside their directories, use unbounded memory or disk, or hang the prompt. Credentials no longer show up in install paths, lockfiles, logs or redirects.
Added
  • {{ mise_config_dir }} template variable. It resolves to the config directory mise itself uses: MISE_CONFIG_DIR, or else xdg_config_home + /mise. It is available wherever xdg_config_home is: config templates, .miserc.toml and settings paths. This is useful for dotfiles variants that link into conf.d. #​14886 (@​jdx, @​ponko2)

    [dotfiles."git-tools"]
    source = "git"
    mode = "symlink"
    variants = [{ default = true, target = "{{ mise_config_dir }}/conf.d/git-tools" }]
  • Semantic highlighting in mise lsp. Editors can now color task names, tools, env vars, [vars] keys, _. directives, {{ }}/{% %}/{# #} template delimiters and deprecated keys in mise.toml. To turn it off, pass {"semanticTokens": false} in initializationOptions. #​14918 (@​jdx)

  • extract_max_ratio setting (global only). It caps how far an archive may expand during extraction. See Security below. #​14915 (@​jdx)

  • github.enterprise_hosts setting (global only, MISE_GITHUB_ENTERPRISE_HOSTS). It lists the GitHub Enterprise hosts that receive the GitHub token on /api/v3 URLs over https. #​14913 (@​jdx)

  • New vfox attestation fields slsa_source_repository and slsa_source_tag. Plugins can use them to pin the repository and tag that SLSA provenance must come from. #​14904, #​14924 (@​jdx)

Changed
  • lockfile_mode = "generate" is now the default. Installs now rebuild mise.lock from the current requests, reuse unchanged entries and also lock the other platforms. A lockfile committed from one machine therefore no longer fails mise install --locked on another platform because of missing entries. Neither mode creates a lockfile (use mise lock or lockfile = true), and the lockfile format is unchanged. To keep the previous behavior, set lockfile_mode = "merge" or MISE_LOCKFILE_MODE=merge. #​14893 (@​jdx)
Security

Trust and safe mode

  • Several actions no longer count as consent to trust a project: printing mise run --help/mise watch --help, running a shim, a hook starting mise run, an MCP call, or mise set/unset/tasks add saving config. Config writes now ask before they trust an untrusted sibling config. A task counts as trusted only if every config that adds to it is trusted. The MCP server refuses untrusted file tasks, task names that look like file paths, and inline tool options. #​14903 (@​jdx)

  • Trust now stays with the files you trusted. A forged git worktree, a symlink to your global config, a clone named .mise, or a project .miserc.toml can no longer borrow trust or hide global config. In paranoid mode, idiomatic version files, each local task file and project-named aqua registries need trust of their own. Remote git includes pinned to a commit SHA must check out exactly that commit. #​14902 (@​jdx)

  • Safe mode (MISE_SAFE=1) now also blocks:

    • a project's lazy tools, [deps], path: versions and spm install_command;
    • all S3 requests;
    • forge tokens and netrc credentials sent to hosts that project config names;
    • env and filesystem helpers in project templates.

    In every mode, a project .miserc.toml gets a restricted, size-limited template language, and bin_path must stay inside the tool's install directory. #​14900 (@​jdx)

  • Pressing TAB no longer runs untrusted task code. The dynamic completers (complete run=, complete delegate=, choices run=, mount) only run for trusted config. mise's own completers quote typed words, and control characters are removed from candidates. Quoting for fish and PowerShell is also fixed. #​14898 (@​jdx)

  • Hook commands are now rendered once, when they load. Before, a directory name containing {{ exec(...) }} could run code from a cd hook. A project's enter, leave and watch_files hooks now start in the project root. mise use, mise upgrade --bump and every other writer refuse to write a version containing template syntax, and a rewritten option keeps its {{ env.X }} template instead of the rendered secret. #​14897 (@​jdx)

  • cd-ing into a hostile repository can no longer hang or crash hook-env or make mise print files from outside the repo. Causes this covers include configs linked to devices, symlink mazes in task directories, non-UTF-8 paths, oversized files, glob characters in paths, and version files that link to another file. #​14916 (@​jdx)

Install verification

  • A checksum pinned in mise.lock is now enforced for erlang, npm, spm and http instead of being replaced or skipped. If Node's SHASUMS256.txt.sig is missing, the install fails. bun and deno check the publisher's sha256 when there is no lock entry. A locked node or spm artifact that returns 404 no longer silently falls back to a source build. #​14899 (@​jdx)

  • SLSA, attestation and signed-checksum checks now fail closed:

    • the provenance file can no longer stand in for the artifact;
    • slsa_signer_* pins require provenance;
    • mise lock runs the cosign, minisign and SLSA checks that aqua recipes declare;
    • SHA-512 signed checksum files are compared with the artifact;
    • aqua honors attestations_since.

    #​14908 (@​jdx)

  • The SLSA signing run must come from the workflow's repository or the tool's own repository. Attestations must name the requested repository. Public-good bundles without a Rekor entry are rejected. #​14904 (@​jdx)

  • SLSA provenance built from a different tag is now rejected, so a mirror can't serve an older release's genuine artifact and provenance as a newer version. #​14924 (@​jdx)

  • packslip signer pins are checked by repository ID, including workflow pins. Backdated GitLab released_at dates and bundles with no transparency-log time can no longer get around minimum_release_age. #​14912 (@​jdx)

Paths, subprocesses and resource limits

  • Release asset names must be plain file names. Archives from the github, http, aqua, cargo-binstall, packslip and vfox backends may not contain symlinks that point outside the install directory. #​14895 (@​jdx)

  • Resolved versions, plugin names and task stub names are checked before they become paths or URL segments. A remote version containing .., quotes, $ or a leading - now fails as an invalid tool version. #​14901 (@​jdx)

  • Git lookups, build tools (ruby-build, python-build, cargo install, gem install) and npm now run outside the project directory, so the repo's .git/config and other project files can't change what they do. Untrusted values are kept out of their command-line arguments. In safe mode, asdf exec-env is refused. #​14896 (@​jdx)

  • Committed symlinks around lockfiles, tool stubs and the remote task cache can no longer make mise read, write or delete files outside the repo. An untrusted lockfile still pins versions and checksums, but it can no longer switch a tool's backend, add inline options or supply download URLs. #​14906 (@​jdx)

  • The task sandbox has fewer escapes:

    • --allow-write refuses project symlinks that lead outside the project;
    • --deny-net also blocks other socket families, io_uring and x32 syscalls;
    • an empty allow_write blocks all writes instead of turning the sandbox off;
    • macOS always uses /usr/bin/sandbox-exec;
    • OCI whiteouts can't delete through planted symlinks.

    #​14911 (@​jdx)

  • HTTP response bodies are capped at 128 MiB, and slow bodies are bounded by http_download_timeout. Downloads are saved exactly as sent. Archive extraction stops once the output exceeds both 256 MiB and 100 times the download size (extract_max_ratio). #​14915 (@​jdx)

Credentials

  • The GitHub token is sent only to GitHub API hosts or the configured api_url, not to any host that serves /api/v3. Release caches are keyed by the exact repository. A download that fails its pinned checksum is not kept. A project can no longer mark a task global. In safe mode, remote task files from project config are not fetched. #​14913 (@​jdx)
  • Credentials are now kept out of install directory names, install manifests, mise.lock, Referer headers, logs and error messages. Age keys and Forgejo tokens are redacted in mise doctor, mise settings and mise tool. Shebang task scripts are readable only by their owner, and multi-line secrets are redacted in task output. #​14917 (@​jdx)
Fixed
  • uv_venv_auto could fork-bomb the machine when uv probed mise's python shims while creating a venv. mise now skips venv creation when it is started from inside that venv creation. #​14927 (@​jdx)
  • With minimum_release_age set, mise upgrade no longer downgrades tools that use date versions with leading zeros (for example 2026.10.21 to 2026.08.19). #​14923 (@​jdx)
  • File tasks that extends a task template now use the template's usage spec, so its flags show in -h and are accepted. #​14888 (@​jdx)
  • mise tasks add --file now quotes and escapes #MISE header values. Before, --dir and values containing quotes produced invalid TOML that broke the next mise run. #​14925 (@​xucian)
  • mise uninstall can now remove installs whose directories deny their owner write access, such as read-only 0555 runtime trees. #​14883 (@​HengYangDS)
  • A pypi: tool with a private git+ssh:// github.com source now lists versions through git ls-remote over SSH when GitHub can't see the repository. #​14905 (@​jdx, @​owpac)
Breaking Changes

Most setups need no changes. Check these cases:

  • Lockfiles: installs now rewrite mise.lock in generate mode. To keep the old behavior, set lockfile_mode = "merge".
  • Trust prompts: mise set/unset/tasks add in a directory with an untrusted sibling config now ask for trust, or fail without a terminal. A project that has only a mise-tasks/ directory needs mise trust . before its dynamic task completions work. In paranoid mode, run mise trust <file> once for each existing task file.
  • Worktrees and includes: a worktree you moved by hand needs git worktree repair before it shares trust again. A remote include pinned to an annotated tag's object ID must pin the commit SHA instead. Your own ~/.miserc.toml can no longer ignore the global config.
  • Project .miserc.toml: templates that read env or use loops or functions other than arch(), os(), os_family(), libc(), avx2() and num_cpus() are no longer rendered. Move them to the global .miserc.toml.
  • Safe mode: project templates that read an env var without a default now fail to render. Projects that point at a private forge or a netrc-protected server can no longer list versions there.
  • Node: mirrors that don't copy the .sig files, and early releases without one (for example 4.0.0 and 5.12.0), need node.gpg_verify = false.
  • SLSA: a github: tool that sets slsa_signer_identity but builds from a branch instead of a tag no longer verifies. A lock entry that has a checksum but no provenance installs on the checksum alone; re-run mise lock or set locked_verify_provenance.
  • packslip: after a repository rename, a pin without a repository ID needs mise packslip forget <tool>.
  • GitHub Enterprise: http: tools, aqua packages and remote tasks on /api/v3 URLs no longer get the GitHub token automatically. Add the host to github.enterprise_hosts in global config, or set api_url.
  • Credentials in URLs: mise lock refuses URLs whose query has a credential-like parameter. Use headers or netrc instead. Tools installed under a directory name that contained credentials are reinstalled under a clean name.
  • Task sandbox: --deny-write/allow_write sandboxes no longer start on Linux before 6.2. Programs that need io_uring no longer run under --deny-net. To allow writes through a project symlink that points outside the project, name its target instead.
  • Archives: archives that contain symlinks pointing outside the install directory fail to install (brew casks and aqua dmg/pkg are exempt). Archives that legitimately expand more than 100 times and past 256 MiB need a higher extract_max_ratio, or 0 to turn the check off.
  • Hooks: a project's enter, leave and watch_files hooks now start in the project root. Use $MISE_PROJECT_ROOT if a hook needs the root explicitly.
  • Other changes:
    • MISE_OVERRIDE_*_FILENAMES entries are matched as literal file names;
    • config, lock and task files over 16 MiB are refused;
    • a .tool-versions or idiomatic version file that links to a file with a different name is skipped;
    • a relative go.repo resolves from $HOME;
    • a bare OWNER/REPO passed to bootstrap --adopt that matches a local path is an error (write ./OWNER/REPO for the local path).
New Contributors

Full Changelog: jdx/mise@v2026.10.18...v2026.10.19

💚 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.

v2026.10.18: : mise lsp: a language server for mise.toml

Compare Source

mise now includes a language server, mise lsp, which gives editors diagnostics, completion, hover, navigation and quick fixes for mise.toml. Doctor checks can depend on other checks, and mise dot history purge erases a tracked file from dotfiles history. This release also fixes many lockfile, prune, Windows and dotfiles issues.

Added
  • mise lsp, a language server for mise config files. It runs over stdin/stdout, so any editor with an LSP client can use it (Neovim, Helix, Emacs, Zed, VS Code, ...). It uses the schema and formatter of the installed mise, so its answers match your version. #​14744, #​14808, #​14811, #​14812 (@​jdx)

    • Diagnostics: TOML syntax errors, unknown keys with a "did you mean" suggestion, values of the wrong type, and deprecated keys. It warns about task references that point to no task and reports depends cycles as errors.
    • Completion and hover: config keys and enum or boolean values, task names in depends, depends_post, wait_for, run = [{ task = ... }] and extends, and tool names from the registry under [tools]. Hover shows the description and backends of a tool, or the description and command of a task.
    • Navigation and editing: go to a task's definition (also in included files), find its references, and rename a task together with every reference in the file. Quick fixes replace an unknown key or task name, and rewrite a deprecated key such as env_path to the key that replaces it. Formatting gives the same output as mise fmt.
    • It only handles files that mise loads as configs (mise.toml, mise.<env>.toml, conf.d/*.toml, ...) and ignores Cargo.toml, pyproject.toml and other TOML files, so you can attach it to the TOML filetype. Configs are parsed but never rendered, and it makes no network requests, so opening an untrusted file runs nothing. Clients can turn off formatting, hover, completion, definition, references or rename with initializationOptions.
    vim.lsp.config("mise", { cmd = { "mise", "lsp" }, filetypes = { "toml" }, root_markers = { "mise.toml" } })
    vim.lsp.enable("mise")
  • Doctor checks can depend on other checks. Add depends (a single name or a list) to a check in [doctor.checks.*]. If a dependency fails, errors, is skipped or is blocked, the dependent check is reported as blocked, and its command and hint are skipped. A blocked result does not change the exit code on its own. An unknown dependency name or a cycle is reported as a config error, and then no checks run. #​14773 (@​jdx)

    [doctor.checks."examplectl:project"]
    depends = ["examplectl:auth"]
    run = 'test -n "$(examplectl config get project)"'
  • mise dot history purge <path> removes a tracked path from local dotfiles history. Use it after tracking a secret by mistake. Checkpoints that changed only that path are removed. All other checkpoints keep their numeric IDs, messages and dates, so history, rollback and undo keep working. Use --dry-run to preview and --yes to skip the prompt. --backup keeps the old history under refs/mise/purge-backup/, and --keep-objects skips pruning. The command refuses if any version of the path is already reachable from the origin, because mise never force-pushes. #​14831 (@​jdx)

  • A dotfiles variant's target can be a template, so one shared config can link into locations that differ between machines. Only the variant target is rendered. Templates get the standard config context (env, xdg_config_home, config_root, ...), but exec() and vars are not available. The rendered path must be absolute or start with ~/. #​14856 (@​jdx, @​ponko2)

    [dotfiles.examplectl]
    source = "dotfiles/examplectl"
    mode = "symlink"
    variants = [{ default = true, target = "{{ xdg_config_home }}/examplectl" }]
  • mise upgrade --bump --pin writes resolved versions to config. Requests such as latest or 20 become the exact version, for example 24.14.0, even if the tool was already up to date. With the pin setting (MISE_PIN=1), a plain mise upgrade --bump now does the same. --dry-run shows what would change. #​14791 (@​jdx)

  • [bootstrap.hooks] tables accept run_windows, as tasks and [hooks] already do. On Windows it is used instead of run. A table with only run_windows does nothing on other platforms. #​14851 (@​jdx)

  • Registry: goose-agent (aqua:aaif-goose/goose), the Goose AI agent CLI. The installed binary is still named goose. #​14822 (@​kwsantiago)

Changed
  • pin now also affects a plain mise upgrade --bump. If you have pin enabled, your next mise upgrade --bump rewrites non-exact requests such as "22" to exact versions such as "22.1.0". Without pin, requests keep their precision as before. #​14791 (@​jdx)
  • mise unuse tool@version only prunes the version you named. It used to prune every unused version of the tool. If the named version is kept, mise now explains why, for example node@24.20.0 is kept: required by ~/proj/mise.toml. mise unuse node without a version still prunes all unused versions of node. #​14863 (@​jdx, @​Strepto)
Fixed
Lockfiles
  • If a pipx tool selects its own Python (python = "3.12"), mise use, mise up -l, mise lock pipx:... and mise lock python now keep both that Python and the project's Python in mise.lock. Before, one entry was dropped and mise install --locked failed. #​14794 (@​jdx, @​AllDmeat)
  • mise install tool@latest no longer fails with "lockfile contains multiple resolutions" when nested configs pin different versions. The nearest lockfile now decides. #​14818 (@​jdx)
  • When a monorepo root config is in .config/mise.toml, the shared lockfile is now written to .config/mise.lock instead of <root>/mise.lock. #​14860 (@​jdx, @​fxsalazar)
  • mise lock for pipx: and pypi: tools now accepts PyPI simple indexes that respond with a PEP 691 +html content type, such as Azure Artifacts. #​14852 (@​jdx, @​alexanderlinne)
  • Locked conda installs reuse cached downloads whose checksum is known, instead of downloading the package again. #​14866 (@​zeitlinger)
Install, upgrade and prune
  • A project-level [hooks].postinstall now runs with the version that was just installed. Before, during mise upgrade of a fuzzy request such as latest, its PATH pointed at the old version. #​14853 (@​jdx, @​sam9191)
  • mise prune no longer aborts with "points to an unknown mise Python installation" when a pypi/pipx tool's receipt reaches mise's Python through a minor-version link such as python/3.14. #​14857, #​14874 (@​jdx, @​chancez)
  • With MISE_OVERRIDE_TOOL_VERSIONS_FILENAMES set, tracked .tool-versions files are still loaded. Before, mise prune could remove versions that those projects still used. #​14779 (@​jdx)
  • java = "latest" now selects the newest installed build when two installed versions differ only after + (for example +7 and +101). #​14876 (@​jdx, @​javabrett)
  • gem: installs and bundle install no longer fail when mise is not on PATH. This applies to Rubies installed with this release or later. #​14850 (@​jdx, @​fxsalazar)
  • packslip tools no longer warn on every mise outdated or mise up about skipping a version that is past the minimum_release_age cutoff when that version is already installed. #​14835 (@​jdx, @​alx-xo)
  • Homebrew tap formulae that define their own Requirement classes no longer break mise bootstrap packages apply. mise does not enforce these requirements and logs a warning about them. #​14807 (@​jdx)
  • mise oci build images that include rust now contain a working cargo and rustc, with CARGO_HOME and RUSTUP_HOME set, so containers no longer download the toolchain again on first use. The build now fails if rust comes from a rustup that mise does not manage. #​14854 (@​jdx, @​eiswind)
Network and backends
  • In official rustls Linux builds, mise falls back to its bundled Mozilla root certificates, with a warning, when no system CA certificates can be loaded (for example in minimal containers, or when SSL_CERT_FILE points to a missing file). Roots that do load are not changed. #​14817 (@​jdx)
  • GitHub assets now download correctly when .netrc has credentials for github.com. The reachability check no longer sends those credentials, which had caused a fallback to the rate-limited API. #​14786 (@​jdx)
  • github: tools for which mise-versions returned an empty release list (such as github:caarlos0/svu) now fall back to paged listing, so their versions are found. #​14877 (@​jdx)
  • Expired glab OAuth2 tokens are now ignored instead of sent. This fixes 401 Unauthorized errors when installing gitlab: tools from public projects. #​14873 (@​jdx, @​chung1905)
Windows
  • Zip archives that contain read-only files, such as the Flutter SDK, now extract without "Access is denied". #​14869 (@​jdx, @​akiWagashi)
  • uv-locked pipx: tools whose console script names end in .py (for example pipx:clang-format) now install. #​14825 (@​jdx)
  • In tasks, run_windows = [] now skips the task on Windows instead of running run. #​14859 (@​jdx)
Tasks, bootstrap and generate
  • mise tasks list now works as an alias for mise tasks ls. If you have a task named list, that task still runs. #​14878 (@​jdx, @​mcstafford-git)
  • mise bootstrap no longer fails when a namespaced task such as system:bootstrap exists but no task is named exactly bootstrap. #​14858 (@​jdx)
  • mise generate install-script --write and mise generate task-stubs now write files that end with a newline. Existing stubs regenerate as before. #​14819 (@​itochan)
  • curl https://mise.run | sh no longer fails when ~/.config/curlrc sets write-out. #​14830 (@​jdx)
Dotfiles
  • A mode = "track" entry declared in a config.<env>.toml stays tracked on machines that don't select that env. Before, those machines published a removal of the entry. #​14815 (@​jdx)
  • One saved enrollment under a parent directory that is now a symlink no longer stops automatic capture for all other tracked paths. It is reported as invalid instead. #​14871 (@​jdx)
  • The JSON schema now declares the keys of [dotfile_groups.<name>.entries], so strict validators such as Tombi accept valid entries and report unknown keys. #​14810 (@​jdx)
Other
  • The aqua registry built into mise is now encoded the same way on every build, so builds of the same source are reproducible. #​14809 (@​jdx)
Performance
  • mise now checks trusted_config_paths after the cheaper trust rules and resolves each entry at most once per process. This speeds up hook-env when entries are on slow mounts such as autofs /home on macOS. #​14875 (@​jdx)
Documentation
  • The dotfiles docs now explain repo-only files, how existing repos fit in, undoing an accidental track, and what add --no-apply, dot diff and exclude do. #​14829, #​14862 (@​jdx)
New Contributors

Full Changelog: jdx/mise@v2026.10.17...v2026.10.18

💚 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.

v2026.10.17: : Shell names in bootstrap login_shell, templated doctor checks, and a per-plugin vfox cache directory

Compare Source

bootstrap.user.login_shell now accepts a shell name such as fish instead of a full path. [doctor.checks] can use templates, and vfox backend plugins get their own cache directory. This release also fixes PATH handling in zsh setups that deduplicate PATH, stale task cache hits, a pipx interpreter mix-up on macOS, and removes trust in the compromised eMudhra CA certificates.

It also includes the changes prepared for 2026.10.16, which was tagged but never published: relative and templated write_targets paths, version aliases from vfox backend plugins, keyring passwords for private PyPI indexes, vfox-backend: packslip plugin sources, and a change to where find_up starts (see Changed and Upgrading).

Added

  • [bootstrap.user].login_shell accepts a shell name. A config shared across machines no longer needs to know where each system installs the shell. mise looks up the name when it checks or applies the setting, which happens after bootstrap.packages has installed the shell. It searches PATH first (never the mise shims directory), then common package-manager locations: /opt/homebrew/bin, /usr/local/bin, /home/linuxbrew/.linuxbrew/bin, ~/.linuxbrew/bin, /usr/bin and /bin. If no executable is found, mise bootstrap user apply fails without changing /etc/shells or the account, and status reports not installed. mise bootstrap user status shows the path it found, and --json output has a new resolved field. Absolute paths work as before. #​14770 (@​jdx)

    [bootstrap.packages]
    "brew:fish" = "latest"
    
    [bootstrap.user]
    login_shell = "fish"
  • Doctor checks support templates. run, description and hint in [doctor.checks.*] are rendered with the template context of the config file that declares them, the same way hooks are. A check can now use a value from [vars] instead of hard-coding it. dir is not rendered. If a template fails, only that check reports ERROR and the other checks still run. Text that already contains {{ or {% in these fields is now parsed as a template. #​14771 (@​jdx)

    [doctor.checks."project-a:env"]
    description = "project-a has a .env file"
    run = 'test -f {{ vars.repos_dir | quote }}/project-a/.env'
    hint = "cp {{ vars.repos_dir }}/project-a/.env.example {{ vars.repos_dir }}/project-a/.env"
  • vfox plugins get RUNTIME.cacheDirPath. This is a cache directory for each plugin at $MISE_CACHE_DIR/plugins/<plugin-name>. mise creates it before running any hook, and every hook of the plugin sees the same path. Unlike pluginDirPath, it is kept when the plugin is reinstalled. mise cache clear deletes it, so plugins must handle it being missing. It is nil when no cache directory is available. #​14776 (@​jdx)

  • settings.write_targets accepts relative and templated paths. Before, only absolute or ~/ paths worked, so dotfiles shared between machines with different MISE_CONFIG_DIR or XDG_CONFIG_HOME had to hardcode the config directory. Templates are now rendered, and a relative result is joined to the config_root of the settings file that declares it. For a global file that is $HOME, so the portable spelling uses the file's own directory. The resolved path must still be a global config file that mise loads. If a template fails to render, mise warns, and mise use --global fails with "must resolve to an absolute path" instead of writing to the default file. #​14742 (@​jdx)

    # ~/.config/mise/conf.d/settings.toml
    [settings.write_targets]
    tools = "{{ config_source | dirname }}/tools.toml"
  • vfox backend plugins can report version aliases. BackendListVersions can return an aliases table, so a registry's moving names resolve to real versions. Before, "mise-ghcup:ghc" = "recommended" passed the literal string to the plugin, installed into installs/.../recommended, never followed the tag when it moved, and showed recommended in mise ls and the lockfile. Now ghc@recommended resolves to 9.10.3, installs into 9.10.3/, and the lockfile records 9.10.3. Aliases you define in config still win. They are cached like the version list, and an expired cache still answers offline. Older mise versions ignore the aliases field, so plugins can adopt it right away. #​14732 (@​jdx, @​cprecioso)

    return {
      versions = { "9.8.4", "9.10.3", "9.14.1" },
      aliases = { recommended = "9.10.3" },
    }
  • mise lock and version listing work with a PyPI index that uses a keyring. With an index such as Azure Artifacts and artifacts-keyring, mise install worked because uv read the password from its keyring provider, but mise's own requests sent no credentials and failed with 401 Unauthorized. Set the new pypi.keyring_provider (disabled by default, or subprocess; env var MISE_PYPI_KEYRING_PROVIDER) and give the registry URL a username without a password. mise then runs keyring get <url> <username>, as uv does, and sends the result as HTTP Basic credentials when it lists versions and when mise lock reads a release's requires-python. The password is never written to the lockfile or the version cache. The keyring executable must be on PATH. If it is missing or has no entry, mise sends the request without credentials. #​14733 (@​jdx)

    [settings.pypi]
    keyring_provider = "subprocess"
    registry_url = "https://VssSessionToken@pkgs.dev.azure.com/org/project/_packaging/feed/pypi/simple/{}/"
  • vfox-backend: works as a prefix for packslip plugin sources. A vfox backend plugin can be installed from a signed packslip archive, both from the CLI and in [plugins]. Before, mise plugins install vfox-backend:foo 'packslip:owner/repo#1.0.0' failed with packslip plugin sources require the vfox plugin type. An explicit asdf: or package: prefix is still rejected, and the error now says "vfox or vfox-backend". The archive still declares extensions.mise.plugin = "vfox". #​14727 (@​jdx)

    mise plugins install vfox-backend:my-backend 'packslip:your-org/my-backend#1.0.0'
  • mise bootstrap packages list is now an alias for status, alongside ls. #​14709 (@​himkt)

Changed

  • find_up in env._.file starts at the config root. Every other relative path in a config resolves against the config root, but find_up started at the current directory. A relative find_up path now starts at the config root and walks up through its parents, which suits a monorepo whose root .env applies to every package. An absolute path starts at its own directory. A global config that wants to search from wherever mise runs can use cwd. The env_file setting still discovers dotenv files up from the current directory and is unchanged. See Upgrading. #​14734 (@​jdx, @​thernstig)

    # ~/.config/mise/config.toml
    [env]
    _.file = { path = "{{cwd}}/.env", find_up = true }
  • allow_builds approves only the packages it lists. With the embedded aube installer, allow_builds = ["re2"] also ran the install scripts of every package on aube's bundled trusted-dependencies list, such as dtrace-provider. For a package list, mise now turns that default list off, so only the packages you name build. allow_builds = true and the default with no option are unchanged. This updates the embedded aube to 2.8.0. #​14731 (@​jdx)

Fixed

  • exec() in [env] values, and other commands mise runs with the pre-activation environment, can now find commands in a _.path directory that was already on PATH before activation, even if the shell deduplicates PATH (for example zsh with typeset -U path PATH). #​14772 (@​jdx)
  • With task.source_freshness_hash_contents = true, a task now re-runs when a source file is changed to content of the same size and its old mtime is restored (for example by rsync -a, cp -p or touch -r). On Unix, mise now also compares the file's ctime. Cache entries written by older versions are rehashed once. #​14778 (@​jdx)
  • On macOS, pipx: installs no longer fail when aqua:aws/aws-cli is in the toolset. Because macOS filesystems ignore case by default, mise's lookup for python matched aws-cli's executable Python shared library and passed it to uv as the interpreter. This lookup now requires the exact case. #​14769 (@​jdx)
  • An aqua registry template with an unterminated string literal now fails with an "unterminated string literal" error instead of hanging. Escaped quotes after backslashes are also detected correctly. #​14752 (@​Huge, @​jdx)
  • The built-in npm backend no longer trusts the eight eMudhra intermediate CA certificates whose private keys were compromised. The fix comes from updating its bundled root certificates (webpki-root-certs 1.0.10, rustls-webpki 0.103.16). Builds that use the OS trust store are fixed by OS updates instead. #​14781 (@​jdx)
  • A [bootstrap.compose] project no longer reports drift on every run when a service uses a service: reference such as network_mode: service:vpn. Compose hashes the reference as written but stamps the container with the hash of the resolved container:<id>, so the two never matched. mise now pins these references (network_mode, ipc, pid, volumes_from) to the running container before it asks compose for the hash. This needs an explicit files list in the project's config. Projects without one hash as before. #​14729 (@​jdx)
  • vfox plugins now keep symlinks when they extract .zip archives returned by PreInstall. Before, entries such as bin/npm -> ../lib/node_modules/npm/bin/npm-cli.js became regular files holding the link target, and the tool failed with No such file or directory. Links that resolve outside the install directory are still rejected. The http: backend and tarballs were not affected. #​14730 (@​jdx)
  • [daemons.<name>] task = "worker" now finds a file task such as .mise/tasks/worker.sh, as mise run worker does. Before, it failed with daemon srv runs unknown task "worker" unless you wrote worker.sh. #​14741 (@​jdx)
  • On Windows, mise self-update no longer replaces the winget mise-shim.exe link with a copy. It updates the real mise-shim.exe next to the real mise.exe. Before, mise reshim kept warning that the shim was older than mise. #​14737 (@​jdx)
  • An inherited [dotfiles] entry turned off with only enabled = false no longer prints no recognized operation (block, source, or line), ignoring entry on every command. Other tables with no recognized operation, such as a misspelled line, still warn. #​14726 (@​jdx, @​ponko2)

Upgrading

  • find_up in a global config: a relative find_up entry in env._.file used to search from the current directory. It now searches from the config root, which is ~ for a global config, so it no longer finds project files. To keep the old behavior, put {{cwd}}/ in front of the path. find_up was added in 2026.10.12.

Documentation

  • The dotfiles docs now explain that a group entry with only permissions does not inherit the group's mode, so it deploys nothing. Removing mode from an entry that used to deploy a file leaves that file orphaned, and --prune deletes it. To deploy a file and set its permissions, use { mode = "copy", permissions = "0600" }. #​14768 (@​jdx)

New Contributors

Full Changelog: jdx/mise@v2026.10.15...v2026.10.17

💚 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.

v2026.10.15: : Default minimum_release_age covers every backend, plus a PowerShell installer

Compare Source

The default 24-hour minimum_release_age now applies to every backend. Many more backends report release dates, so the cooldown can actually hold new versions back, and mise warns when it installs a version it couldn't date. This release also adds a PowerShell installer for Windows, read_json/read_yaml/read_toml template functions, dotnet@lts/dotnet@sts, and new dotfiles options.

Changed

  • The default minimum_release_age applies to every backend. The built-in 24h cooldown used to cover only backends that reported release dates (aqua, cargo, core, github, npm, pypi and others). asdf, vfox, conda, dotnet, http: and s3: tools had no cutoff at all. Now every backend gets the cooldown. A tool whose only version is less than 24h old now resolves to "no versions found", as aqua and github tools already did. To opt a tool out, add it to minimum_release_age_excludes. To turn the cooldown off, set minimum_release_age = "0s". #​14701 (@​jdx)

  • mise warns when it can't check a version's release date. A version with no known date still passes the cutoff, but mise install, mise upgrade and mise use now print a one-time warning naming the version. Exact pins you wrote yourself don't trigger it. mise env, mise ls, mise outdated and mise ls-remote never print it. #​14694 (@​jdx)

    WARN  asdf:tiny@3.1.0 has no release date, so the ... cutoff cannot be checked and it is allowed (exclude it with minimum_release_age_excludes to silence this)
    
  • More backends report release dates, so the cooldown applies to them:

    • conda versions use the channel's earliest index timestamp. #​14693
    • aqua packages that take versions from git tags (version_source: github_tag, such as aws/aws-cli, docker/cli and cockroachdb/cockroach) are now dated. #​14691
    • dotnet dates come from Microsoft's releases index. deno and erlang dates come from their GitHub releases. #​14692
    • Every python version now has a date, and so do many more ruby versions (from ruby-lang.org, Maven Central for JRuby, and GitHub for TruffleRuby). Rust's stable, beta and nightly channels are dated too. With an explicit past cutoff, rust@stable resolves to the newest stable release that is old enough, and beta/nightly resolve to a dated build from before the cutoff. #​14697
    • The dart, flutter, nim, julia, nomad-pack, sentinel, tfc-agent, android-cli, cursor-agent and twg registry tools now report dates. #​14698

    All by @​jdx.

  • Version lists for more backends come from the mise-versions host. npm:, pipx:, cargo:, gem:, go:, dotnet: and spm: tools now list versions from mise-versions, like other registry tools, instead of going to their own source. So do http/s3 tools with a version_list_url. If you redirect a source, mise still lists from that source directly. That covers a custom npm registry or npm.shell_out, pypi.registry_url, a non-default GOPROXY, cargo.registry_name, a custom gem source, dotnet.registry_url, S3 endpoint overrides, and local listing options. conda always lists from its channel. The host cache TTL now follows the tool's minimum_release_age. To list everything from the source, set MISE_USE_VERSIONS_HOST=0. #​14700 (@​jdx)

Added

  • PowerShell installer for Windows. It's published with each release as install.ps1 and served from mise.run at /powershell and /pwsh, so you pipe it into iex with irm. It works on PowerShell 5.1+ and doesn't need admin rights. It installs the newest release that is at least 24h old, or MISE_VERSION if set. The download is verified against SHASUMS256.txt from GitHub Releases. mise.exe and mise-shim.exe go into ~\.local\bin, and that directory is added to your user Path. Re-running it upgrades an existing install. Options include MISE_INSTALL_PATH, MISE_INSTALL_MODIFY_PATH=0, MISE_INSTALL_SHIMS_PATH=1 and MISE_INSTALL_FROM_GITHUB=1. See the "Installing mise" docs for the full command. #​14660 (@​jdx, @​lhs-12)

  • read_json(), read_yaml() and read_toml() template functions parse a file so a template can use a value from it. This saves copying a version from package.json or Pulumi.yaml into mise.toml by hand. Relative paths resolve from the config file's directory. A missing key is an error unless you add | default(value="..."). Like read_file(), these functions need a trusted config, and they don't work in safe mode, .miserc.toml or OCI dotfile templates. #​14705 (@​jdx, @​edahlseng)

    [tools]
    node = "{{ read_json(path='package.json')['volta']['node'] }}"
    pulumi = "{{ read_yaml(path='Pulumi.yaml')['requiredPulumiVersion'] }}"
  • dotnet@lts and dotnet@sts resolve to the newest SDK in the current LTS or STS channel, using Microsoft's release index. Preview, go-live and end-of-life channels are skipped. A lts alias you define in [tool_alias.dotnet.versions] still takes precedence. Runtime-only installs still need an exact version. #​14683 (@​jdx)

  • mise bootstrap --prune-dotfiles removes dotfiles that are no longer deployed, the same way mise dot apply --prune does, so mise bootstrap --upgrade --prune-dotfiles handles everything in one run. The prune runs at the end of the dotfiles phase. It respects --dry-run, --yes and --skip dotfiles. Copies you edited are left in place. [#​14681](https://

[!IMPORTANT]
✂ PR body was truncated to here.


Configuration

📅 Schedule: (in timezone America/Los_Angeles)

  • Branch creation
    • At any time (no schedule defined)
  • Automerge
    • At any time (no schedule defined)

🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

♻ Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about this update again.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.

@renovate renovate Bot added the bot label Jul 20, 2026
@renovate
renovate Bot force-pushed the renovate/jdx-mise-2026.x branch 6 times, most recently from b069281 to 4210d96 Compare July 30, 2026 03:03
@renovate
renovate Bot force-pushed the renovate/jdx-mise-2026.x branch 4 times, most recently from 7255dd3 to 18a73a9 Compare August 5, 2026 03:26
@renovate
renovate Bot force-pushed the renovate/jdx-mise-2026.x branch 3 times, most recently from 2752ba1 to 661a5bf Compare August 12, 2026 20:16
@renovate
renovate Bot force-pushed the renovate/jdx-mise-2026.x branch 4 times, most recently from 6445a85 to c5325ef Compare August 20, 2026 23:10
@renovate
renovate Bot force-pushed the renovate/jdx-mise-2026.x branch 4 times, most recently from 9dd559c to fac6f2e Compare August 26, 2026 03:48
@renovate
renovate Bot force-pushed the renovate/jdx-mise-2026.x branch 4 times, most recently from 61548e9 to 844f10e Compare September 3, 2026 00:28
@renovate
renovate Bot force-pushed the renovate/jdx-mise-2026.x branch 4 times, most recently from b504efd to 25c7628 Compare September 11, 2026 04:03
@renovate
renovate Bot force-pushed the renovate/jdx-mise-2026.x branch 3 times, most recently from e80a868 to 39250db Compare September 20, 2026 15:11
@renovate
renovate Bot force-pushed the renovate/jdx-mise-2026.x branch 6 times, most recently from 592af37 to fb21bcb Compare September 30, 2026 23:27
@renovate
renovate Bot force-pushed the renovate/jdx-mise-2026.x branch 6 times, most recently from f1ad039 to 6922c36 Compare October 9, 2026 02:53
@renovate
renovate Bot force-pushed the renovate/jdx-mise-2026.x branch 6 times, most recently from 0aa2b64 to c858e85 Compare October 15, 2026 12:37
@renovate
renovate Bot force-pushed the renovate/jdx-mise-2026.x branch 7 times, most recently from 97dbd7b to 51e9bec Compare October 23, 2026 18:04
@renovate
renovate Bot force-pushed the renovate/jdx-mise-2026.x branch from 51e9bec to 6cb4b31 Compare October 24, 2026 22:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants