Skip to content

fix(backend): skip versions host for direct-source backends#9245

Merged
jdx merged 2 commits intomainfrom
fix/skip-versions-host-for-direct-source-backends
Apr 18, 2026
Merged

fix(backend): skip versions host for direct-source backends#9245
jdx merged 2 commits intomainfrom
fix/skip-versions-host-for-direct-source-backends

Conversation

@jdx
Copy link
Copy Markdown
Owner

@jdx jdx commented Apr 18, 2026

Summary

  • For backends that already query canonical, always-fresh upstream sources, skip the mise-versions.jdx.dev cache and query the source directly.
  • Affected backends:
    • npm (npm registry), pipx (PyPI), cargo (crates.io), gem (RubyGems), go (Go module proxy)
    • http / s3 backends when version_list_url is set (registry provides a canonical source)
  • This avoids the failure mode observed for Flutter where the versions host's cached data had gone stale at 3.22.1-stable, hiding newer releases until users set MISE_USE_VERSIONS_HOST=0.

Refs discussion comment.

Test plan

  • mise ls-remote flutter shows current releases (e.g. 3.38.x/3.41.x) without needing MISE_USE_VERSIONS_HOST=0
  • mise ls-remote for an npm/pipx/cargo/gem/go tool still returns versions
  • http backend tools without version_list_url still use the versions host (unchanged behavior)
  • Existing unit + e2e tests pass

🤖 Generated with Claude Code


Note

Medium Risk
Changes global remote-version listing behavior by conditionally bypassing mise-versions.jdx.dev, which could affect performance and rate-limiting characteristics across multiple backends (especially GitHub-like ones) if the allowlist/version_list_url detection is wrong.

Overview
Adjusts Backend::list_remote_versions_with_info to skip the mise-versions.jdx.dev versions-host cache for backends that already have canonical, always-fresh upstream version sources (notably package registries and http/s3 when version_list_url is set), querying the upstream directly instead.

Introduces backend-type gating and version_list_url detection (including tool/config opts) to decide whether the versions host applies, and adds trace logging to explain when/why the cache is bypassed; all other backends keep the existing “try versions host first, then fall back” behavior.

Reviewed by Cursor Bugbot for commit ce79bc4. Bugbot is set up for automated code reviews on this repo. Configure here.

Backends that query canonical package registries (npm, pipx, cargo, gem,
go) or http/s3 backends with an explicit version_list_url already have
an always-fresh upstream source. The versions host cache
(mise-versions.jdx.dev) in front of those only adds latency and
staleness risk — e.g. flutter's cached data stopped at 3.22.1, hiding
newer releases until users set MISE_USE_VERSIONS_HOST=0.

Skip the versions host for these and query the source directly.

Ref: #7863 (reply in thread)
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Apr 18, 2026

Greptile Summary

This PR skips the mise-versions.jdx.dev versions host for backends that already have canonical, always-fresh upstream sources (npm, pipx, cargo, gem, go, conda, dotnet, spm, and http/s3 when version_list_url is set), fixing the Flutter stale-cache issue where the host had stopped at 3.22.1-stable.

The Flutter fix works correctly because ba.opts() already merges registry-defined options (including version_list_url from registry/flutter.toml), so has_version_list_url evaluates to true for Flutter without any user-level config changes.

Confidence Score: 5/5

Safe to merge — logic is correct, well-commented, and the Flutter fix is verified to work through existing registry option merging.

All findings are P2 or lower. The allowlist approach is sound, the asymmetric override is explicitly documented in code, ba.opts() correctly surfaces registry-defined version_list_url so Flutter bypasses the stale cache, and BackendType::Unknown is effectively a dead path since backends of that type are filtered out before reaching this code.

No files require special attention.

Important Files Changed

Filename Overview
src/backend/mod.rs Adds versions_host_applies allowlist check before querying the versions host; correctly handles Flutter via registry-merged ba.opts(), with clear inline documentation of the asymmetric override behavior.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[list_remote_versions_with_info] --> B{backend_type}
    B -- "Github/Gitlab/Forgejo\nAqua/Ubi/Core/Asdf/Vfox" --> C[versions_host_applies = true]
    B -- "Http / S3" --> D{has_version_list_url?}
    D -- yes --> E[versions_host_applies = false]
    D -- no --> C
    B -- "Npm/Cargo/Gem/Go/Pipx\nConda/Dotnet/Spm/Unknown" --> E

    C --> F{plugin remote\nmatches registry?}
    F -- yes --> G[use_versions_host = true]
    F -- no --> H[use_versions_host = false]

    E --> I[use_versions_host = false\ntrace log bypass]

    G --> J{offline?}
    H --> J
    I --> J

    J -- yes --> K[return empty]
    J -- no --> L{use_versions_host?}
    L -- yes --> M[versions_host::list_versions]
    M -- Some --> N[return versions]
    M -- None/Err --> O[_list_remote_versions]
    L -- no --> O
    O --> N
Loading

Reviews (2): Last reviewed commit: "refactor(backend): invert versions-host ..." | Re-trigger Greptile

Comment thread src/backend/mod.rs Outdated
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces logic to skip the versions host for specific backend types (Npm, Pipx, Cargo, Gem, and Go) and for Http/S3 backends that provide a direct version_list_url. This change aims to reduce latency and avoid staleness by querying sources directly. Feedback suggests expanding the version_list_url check to include options defined in the user's configuration file, ensuring the optimization applies to custom tool configurations as well.

Comment thread src/backend/mod.rs Outdated
Comment on lines +500 to +508
let has_direct_source = matches!(
backend_type,
BackendType::Npm
| BackendType::Pipx
| BackendType::Cargo
| BackendType::Gem
| BackendType::Go
) || (matches!(backend_type, BackendType::Http | BackendType::S3)
&& ba.opts().contains_key("version_list_url"));
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The check for version_list_url currently only looks at ba.opts(), which contains options from the registry or the initial backend argument. However, for http and s3 backends, this option is often defined in the user's config.toml (e.g., in a [tools.mytool] section), which might not be present in ba.opts() if the backend was initialized from a shorthand.

To ensure the versions host is correctly skipped for all custom configurations, you should also check the merged tool options from the config. Since list_remote_versions_with_info is already async and has access to config, you can call config.get_tool_opts(&ba).await? to get the full set of options.

Suggested change
let has_direct_source = matches!(
backend_type,
BackendType::Npm
| BackendType::Pipx
| BackendType::Cargo
| BackendType::Gem
| BackendType::Go
) || (matches!(backend_type, BackendType::Http | BackendType::S3)
&& ba.opts().contains_key("version_list_url"));
let tool_opts = config.get_tool_opts(&ba).await?.unwrap_or_default();
let has_direct_source = matches!(
backend_type,
BackendType::Npm
| BackendType::Pipx
| BackendType::Cargo
| BackendType::Gem
| BackendType::Go
) || (matches!(backend_type, BackendType::Http | BackendType::S3)
&& (ba.opts().contains_key("version_list_url") || tool_opts.opts.contains_key("version_list_url")));

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in ce79bc4 — the check now also consults config.get_tool_opts(&ba).await? so user-defined http/s3 tools with version_list_url in their config are detected in addition to ba.opts().

This comment was generated by an AI coding assistant.

Address PR review feedback:
- List the backend types we *do* want the versions host for (github,
  gitlab, forgejo, aqua, ubi, core, asdf, vfox) rather than the ones we
  don't. Package-registry backends and http/s3-with-version_list_url now
  fall through to the default `_ => false` arm.
- Also consult `config.get_tool_opts` when checking for `version_list_url`
  so user-defined http/s3 tools in config.toml are detected, mirroring
  the lookup pattern in http.rs.
- Update method doc comment to reflect the new conditional behavior and
  note the asymmetry with `settings.use_versions_host`.
@github-actions
Copy link
Copy Markdown

Hyperfine Performance

mise x -- echo

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2026.4.16 x -- echo 21.4 ± 0.4 20.8 25.5 1.00
mise x -- echo 21.9 ± 0.6 21.3 30.4 1.02 ± 0.04

mise env

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2026.4.16 env 21.0 ± 0.9 20.2 33.3 1.00
mise env 21.4 ± 0.3 20.6 23.2 1.02 ± 0.05

mise hook-env

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2026.4.16 hook-env 21.6 ± 0.3 21.1 23.0 1.00
mise hook-env 22.1 ± 0.7 21.2 29.6 1.02 ± 0.03

mise ls

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2026.4.16 ls 19.7 ± 1.0 18.5 34.4 1.00
mise ls 20.5 ± 0.7 19.1 24.6 1.04 ± 0.06

xtasks/test/perf

Command mise-2026.4.16 mise Variance
install (cached) 149ms 153ms -2%
ls (cached) 77ms 80ms -3%
bin-paths (cached) 82ms 84ms -2%
task-ls (cached) 816ms 816ms +0%

@jdx jdx enabled auto-merge (squash) April 18, 2026 17:02
@jdx jdx merged commit dde8f7e into main Apr 18, 2026
50 of 52 checks passed
@jdx jdx deleted the fix/skip-versions-host-for-direct-source-backends branch April 18, 2026 17:04
jdx pushed a commit that referenced this pull request Apr 19, 2026
### 🚀 Features

- **(latest)** add --before flag to mise latest by @risu729 in
[#9168](#9168)
- **(npm)** add aube package manager support by @jdx in
[#9256](#9256)
- **(spm)** add filter_bins option to restrict built executables by @jdx
in [#9253](#9253)
- **(vfox)** support plugin-declared dependencies via metadata.lua by
@ahemon in [#9051](#9051)
- rename `mise prepare` to `mise deps` and add package management by
@jdx in [#9056](#9056)

### 🐛 Bug Fixes

- **(backend)** skip versions host for direct-source backends by @jdx in
[#9245](#9245)
- **(github)** route artifact attestation verification to custom api_url
by @jdx in [#9254](#9254)
- **(lockfile)** use unique temp file for atomic save to avoid
concurrent rename race by @jdx in
[#9250](#9250)
- **(log)** drop noisy third-party debug/trace logs by @jdx in
[#9248](#9248)
- **(progress)** disable animated clx output in ci by @jdx in
[#9249](#9249)
- **(use)** honor --quiet and --silent flags by @jdx in
[#9251](#9251)
- **(vfox)** opt backend plugins out of --locked URL check by @jdx in
[#9252](#9252)

### 📦 Registry

- add aqua backend for bitwarden-secrets-manager by @msuzoagu in
[#9255](#9255)

### New Contributors

- @ahemon made their first contribution in
[#9051](#9051)
- @msuzoagu made their first contribution in
[#9255](#9255)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant