fix(config): make MISE_OFFLINE work correctly by gracefully skipping network calls#8109
fix(config): make MISE_OFFLINE work correctly by gracefully skipping network calls#8109
Conversation
…network calls MISE_OFFLINE=1 previously caused hangs and errors because it blocked all HTTP requests with hard errors, but callers didn't handle these gracefully. Version resolution would fail instead of falling back to local data. This adds proper offline/prefer_offline settings to settings.toml (so they're documented and configurable via mise.toml), adds Settings::offline() and Settings::prefer_offline() convenience methods that combine settings + env vars, and guards all network call sites to gracefully skip remote fetching when offline. Closes #6916 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Summary of ChangesHello @jdx, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request significantly enhances the Highlights
Changelog
Activity
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Pull request overview
Fixes offline-mode behavior so MISE_OFFLINE=1 (and new settings.offline) avoids network calls without breaking version resolution, by centralizing offline/prefer-offline checks in Settings.
Changes:
- Add
Settings::offline()/Settings::prefer_offline()helpers and migrate call sites away from raw env checks. - Skip/short-circuit remote version fetching and tracking when offline/prefer-offline.
- Document and expose
offline/prefer_offlineinsettings.tomland JSON schema.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| src/versions_host.rs | Skip versions-host listing and tracking when offline/prefer-offline. |
| src/toolset/tool_version.rs | Avoid remote version resolution in offline and use Settings helpers. |
| src/http.rs | Gate HTTP requests via Settings::get().offline() rather than raw env flag. |
| src/config/settings.rs | Introduce offline() / prefer_offline() helpers and use them in caching logic. |
| src/backend/mod.rs | Return empty remote versions when offline to avoid network calls. |
| src/aqua/aqua_registry_wrapper.rs | Use Settings::prefer_offline() instead of direct env access. |
| settings.toml | Add documentation and env bindings for offline and prefer_offline. |
| schema/mise.json | Add schema entries for offline / prefer_offline. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
src/toolset/tool_version.rs
Outdated
| return build(v); | ||
| } | ||
|
|
||
| let is_offline = Settings::get().offline(); |
There was a problem hiding this comment.
Settings::get() is called multiple times in the same function, which makes the logic harder to read and could lead to inconsistent behavior if Settings are ever reloaded/mutated. Consider storing let settings = Settings::get(); once and reusing settings.offline() / settings.prefer_offline().
| let is_offline = Settings::get().offline(); | |
| let settings = Settings::get(); | |
| let is_offline = settings.offline(); |
src/toolset/tool_version.rs
Outdated
| if env::PREFER_OFFLINE.load(std::sync::atomic::Ordering::Relaxed) | ||
| && v.matches('.').count() >= 2 | ||
| { | ||
| if Settings::get().prefer_offline() && v.matches('.').count() >= 2 { |
There was a problem hiding this comment.
Settings::get() is called multiple times in the same function, which makes the logic harder to read and could lead to inconsistent behavior if Settings are ever reloaded/mutated. Consider storing let settings = Settings::get(); once and reusing settings.offline() / settings.prefer_offline().
src/aqua/aqua_registry_wrapper.rs
Outdated
|
|
||
| if env::PREFER_OFFLINE.load(std::sync::atomic::Ordering::Relaxed) { | ||
| if Settings::get().prefer_offline() { | ||
| trace!("skipping aqua registry update due to PREFER_OFFLINE"); |
There was a problem hiding this comment.
The trace message still references PREFER_OFFLINE, but the check is now Settings::get().prefer_offline() (which also includes offline). Update the message to reflect the new behavior (e.g., “due to prefer-offline mode”).
| trace!("skipping aqua registry update due to PREFER_OFFLINE"); | |
| trace!("skipping aqua registry update due to prefer-offline mode"); |
| /// Returns true if offline mode is enabled via setting or CLI flag/env var. | ||
| pub fn offline(&self) -> bool { | ||
| self.offline || *env::OFFLINE | ||
| } | ||
|
|
||
| /// Returns true if prefer-offline mode is enabled via setting, env var, or | ||
| /// because the current command is a "fast" command (hook-env, activate, etc.). | ||
| /// Also returns true if offline mode is enabled (offline implies prefer-offline). | ||
| pub fn prefer_offline(&self) -> bool { | ||
| self.offline() || self.prefer_offline || env::PREFER_OFFLINE.load(Ordering::Relaxed) | ||
| } |
There was a problem hiding this comment.
These new precedence/implication rules (offline implies prefer_offline, plus env/setting interactions) are core behavior. Add unit tests covering key combinations (setting-only, env-only, both set, and ensuring offline() forces prefer_offline()), since regressions here will silently change network behavior across many call sites.
There was a problem hiding this comment.
Code Review
This pull request effectively addresses issues with offline mode by introducing offline and prefer_offline settings. The changes are well-implemented, centralizing the offline-checking logic into new methods on the Settings struct. These methods are then used throughout the codebase to gracefully skip network requests, preventing hangs and errors when MISE_OFFLINE is enabled. The addition of schema definitions and documentation for the new settings is also a great improvement. Overall, the changes are solid and I have no concerns.
|
bugbot run |
… tests - Cache Settings::get() in resolve_version() to avoid repeated calls - Update aqua trace message to reflect new prefer-offline mode naming - Add unit tests for offline()/prefer_offline() method behavior Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…s ordering Move offline check before CacheManager closure in list_remote_versions_with_info() to prevent empty version lists from being persisted to disk cache. Fix alphabetical ordering of offline and prefer_offline in settings.toml and schema. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Hyperfine Performance
|
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2026.2.9 x -- echo |
23.4 ± 0.3 | 22.5 | 25.7 | 1.00 |
mise x -- echo |
24.1 ± 0.4 | 22.6 | 27.0 | 1.03 ± 0.02 |
mise env
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2026.2.9 env |
22.5 ± 0.6 | 21.1 | 27.5 | 1.00 |
mise env |
22.8 ± 0.7 | 21.4 | 25.2 | 1.01 ± 0.04 |
mise hook-env
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2026.2.9 hook-env |
22.8 ± 0.5 | 21.8 | 24.0 | 1.00 |
mise hook-env |
24.3 ± 0.9 | 22.8 | 39.2 | 1.07 ± 0.05 |
mise ls
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2026.2.9 ls |
20.8 ± 0.5 | 19.7 | 24.0 | 1.00 |
mise ls |
21.4 ± 0.7 | 20.0 | 25.3 | 1.03 ± 0.04 |
xtasks/test/perf
| Command | mise-2026.2.9 | mise | Variance |
|---|---|---|---|
| install (cached) | 123ms | 124ms | +0% |
| ls (cached) | 76ms | 77ms | -1% |
| bin-paths (cached) | 81ms | 81ms | +0% |
| task-ls (cached) | 554ms | 547ms | +1% |
### 🚀 Features - **(activate)** add shims directory as fallback when auto-install is enabled by @ctaintor in [#8106](#8106) - **(env)** add `tools` variable to tera template context by @jdx in [#8108](#8108) - **(set)** add --stdin flag for multiline environment variables by @jdx in [#8110](#8110) ### 🐛 Bug Fixes - **(backend)** improve conda patchelf and dependency resolution for complex packages by @jdx in [#8087](#8087) - **(ci)** fix validate-new-tools grep pattern for test field by @jdx in [#8100](#8100) - **(config)** make MISE_OFFLINE work correctly by gracefully skipping network calls by @jdx in [#8109](#8109) - **(github)** skip v prefix for "latest" version by @jdx in [#8105](#8105) - **(gitlab)** resolve tool options from config for aliased tools by @jdx in [#8084](#8084) - **(install)** use version_expr for Flutter to fix version resolution by @jdx in [#8081](#8081) - **(registry)** add Linux support for tuist by @fortmarek in [#8102](#8102) - **(release)** write release notes to file instead of capturing stdout by @jdx in [#8086](#8086) - **(upgrade)** tools are not uninstalled properly due to outdated symlink by @roele in [#8099](#8099) - **(upgrade)** ensure uninstallation failure does not leave invalid symlinks by @roele in [#8101](#8101) - SLSA for in-toto statement with no signatures by @gerhard in [#8094](#8094) - Vfox Plugin Auto-Installation for Environment Directives by @pose in [#8035](#8035) ### 📚 Documentation - use mise activate for PowerShell in getting-started by @rileychh in [#8112](#8112) ### 📦 Registry - add conda backend for mysql by @jdx in [#8080](#8080) - add conda backends for 10 asdf-only tools by @jdx in [#8083](#8083) - added podman-tui by @tony-sol in [#8098](#8098) ### Chore - sort settings.toml alphabetically and add test by @jdx in [#8111](#8111) ### New Contributors - @ctaintor made their first contribution in [#8106](#8106) - @rileychh made their first contribution in [#8112](#8112) - @fortmarek made their first contribution in [#8102](#8102) - @pose made their first contribution in [#8035](#8035) - @gerhard made their first contribution in [#8094](#8094) ## 📦 Aqua Registry Updates #### New Packages (2) - [`entireio/cli`](https://github.com/entireio/cli) - [`rmitchellscott/reManager`](https://github.com/rmitchellscott/reManager) #### Updated Packages (1) - [`atuinsh/atuin`](https://github.com/atuinsh/atuin)
### 🚀 Features - **(activate)** add shims directory as fallback when auto-install is enabled by @ctaintor in [#8106](#8106) - **(env)** add `tools` variable to tera template context by @jdx in [#8108](#8108) - **(set)** add --stdin flag for multiline environment variables by @jdx in [#8110](#8110) ### 🐛 Bug Fixes - **(backend)** improve conda patchelf and dependency resolution for complex packages by @jdx in [#8087](#8087) - **(ci)** fix validate-new-tools grep pattern for test field by @jdx in [#8100](#8100) - **(config)** make MISE_OFFLINE work correctly by gracefully skipping network calls by @jdx in [#8109](#8109) - **(github)** skip v prefix for "latest" version by @jdx in [#8105](#8105) - **(gitlab)** resolve tool options from config for aliased tools by @jdx in [#8084](#8084) - **(install)** use version_expr for Flutter to fix version resolution by @jdx in [#8081](#8081) - **(registry)** add Linux support for tuist by @fortmarek in [#8102](#8102) - **(release)** write release notes to file instead of capturing stdout by @jdx in [#8086](#8086) - **(upgrade)** tools are not uninstalled properly due to outdated symlink by @roele in [#8099](#8099) - **(upgrade)** ensure uninstallation failure does not leave invalid symlinks by @roele in [#8101](#8101) - SLSA for in-toto statement with no signatures by @gerhard in [#8094](#8094) - Vfox Plugin Auto-Installation for Environment Directives by @pose in [#8035](#8035) ### 📚 Documentation - use mise activate for PowerShell in getting-started by @rileychh in [#8112](#8112) ### 📦 Registry - add conda backend for mysql by @jdx in [#8080](#8080) - add conda backends for 10 asdf-only tools by @jdx in [#8083](#8083) - added podman-tui by @tony-sol in [#8098](#8098) ### Chore - sort settings.toml alphabetically and add test by @jdx in [#8111](#8111) ### New Contributors - @ctaintor made their first contribution in [#8106](#8106) - @rileychh made their first contribution in [#8112](#8112) - @fortmarek made their first contribution in [#8102](#8102) - @pose made their first contribution in [#8035](#8035) - @gerhard made their first contribution in [#8094](#8094) ## 📦 Aqua Registry Updates #### New Packages (2) - [`entireio/cli`](https://github.com/entireio/cli) - [`rmitchellscott/reManager`](https://github.com/rmitchellscott/reManager) #### Updated Packages (1) - [`atuinsh/atuin`](https://github.com/atuinsh/atuin)
…network calls (jdx#8109) ## Summary - **Fix `MISE_OFFLINE=1` causing hangs/errors** — Previously, offline mode blocked all HTTP requests with hard errors (`ensure!(!*env::OFFLINE, ...)`), but callers didn't handle these gracefully, causing version resolution to fail instead of falling back to local data. - **Add `offline` and `prefer_offline` as proper settings** — Now configurable via `mise.toml` (`settings.offline = true`) and documented, not just env vars. - **Add `Settings::offline()` and `Settings::prefer_offline()` convenience methods** — Combine settings + env vars + CLI flags in one place, simplifying all call sites. ### Key behavior changes: - `versions_host::list_versions()` returns `Ok(None)` when offline/prefer-offline (falls back to local cache) - `versions_host::track_install()` skips when offline - `resolve_version()` skips all remote fetching when offline, returns raw version string - `list_remote_versions_with_info()` returns empty `vec![]` when offline instead of making HTTP calls - `http.rs` ensure checks use `Settings::get().offline()` (covers both setting and env var) - Aqua registry wrapper uses `Settings::prefer_offline()` instead of raw env var access Closes jdx#6916 ## Test plan - [x] `mise run build` — compiles successfully - [x] `mise run lint-fix` — all lints pass - [x] `mise run test:unit` — 469 tests pass - [x] `MISE_OFFLINE=1 target/debug/mise ls` — lists installed tools without errors/hangs - [x] `MISE_OFFLINE=1 target/debug/mise env` — outputs env vars without errors/hangs - [x] `MISE_OFFLINE=1 target/debug/mise settings get offline` — returns `true` - [x] `target/debug/mise settings get prefer_offline` — returns `false` 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Touches core version resolution and remote version listing paths to change behavior under `offline`/`prefer_offline`, which could affect installs and `ls-remote` results if the new gating is too aggressive or mis-detected. > > **Overview** > Adds new `offline` and `prefer_offline` settings (schema + `settings.toml` docs/env bindings) and centralizes their evaluation via `Settings::offline()`/`Settings::prefer_offline()`. > > Updates multiple network/version codepaths to respect these settings: HTTP requests now block based on `Settings::offline()`, remote version listing returns empty when offline, versions-host queries/telemetry and aqua registry updates are skipped when (prefer-)offline, and tool version resolution avoids remote lookups in offline mode (with new unit tests covering defaults and implications). > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit f5fb568. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
### 🚀 Features - **(activate)** add shims directory as fallback when auto-install is enabled by @ctaintor in [jdx#8106](jdx#8106) - **(env)** add `tools` variable to tera template context by @jdx in [jdx#8108](jdx#8108) - **(set)** add --stdin flag for multiline environment variables by @jdx in [jdx#8110](jdx#8110) ### 🐛 Bug Fixes - **(backend)** improve conda patchelf and dependency resolution for complex packages by @jdx in [jdx#8087](jdx#8087) - **(ci)** fix validate-new-tools grep pattern for test field by @jdx in [jdx#8100](jdx#8100) - **(config)** make MISE_OFFLINE work correctly by gracefully skipping network calls by @jdx in [jdx#8109](jdx#8109) - **(github)** skip v prefix for "latest" version by @jdx in [jdx#8105](jdx#8105) - **(gitlab)** resolve tool options from config for aliased tools by @jdx in [jdx#8084](jdx#8084) - **(install)** use version_expr for Flutter to fix version resolution by @jdx in [jdx#8081](jdx#8081) - **(registry)** add Linux support for tuist by @fortmarek in [jdx#8102](jdx#8102) - **(release)** write release notes to file instead of capturing stdout by @jdx in [jdx#8086](jdx#8086) - **(upgrade)** tools are not uninstalled properly due to outdated symlink by @roele in [jdx#8099](jdx#8099) - **(upgrade)** ensure uninstallation failure does not leave invalid symlinks by @roele in [jdx#8101](jdx#8101) - SLSA for in-toto statement with no signatures by @gerhard in [jdx#8094](jdx#8094) - Vfox Plugin Auto-Installation for Environment Directives by @pose in [jdx#8035](jdx#8035) ### 📚 Documentation - use mise activate for PowerShell in getting-started by @rileychh in [jdx#8112](jdx#8112) ### 📦 Registry - add conda backend for mysql by @jdx in [jdx#8080](jdx#8080) - add conda backends for 10 asdf-only tools by @jdx in [jdx#8083](jdx#8083) - added podman-tui by @tony-sol in [jdx#8098](jdx#8098) ### Chore - sort settings.toml alphabetically and add test by @jdx in [jdx#8111](jdx#8111) ### New Contributors - @ctaintor made their first contribution in [jdx#8106](jdx#8106) - @rileychh made their first contribution in [jdx#8112](jdx#8112) - @fortmarek made their first contribution in [jdx#8102](jdx#8102) - @pose made their first contribution in [jdx#8035](jdx#8035) - @gerhard made their first contribution in [jdx#8094](jdx#8094) ## 📦 Aqua Registry Updates #### New Packages (2) - [`entireio/cli`](https://github.com/entireio/cli) - [`rmitchellscott/reManager`](https://github.com/rmitchellscott/reManager) #### Updated Packages (1) - [`atuinsh/atuin`](https://github.com/atuinsh/atuin)
### 🚀 Features - **(activate)** add shims directory as fallback when auto-install is enabled by @ctaintor in [jdx#8106](jdx#8106) - **(env)** add `tools` variable to tera template context by @jdx in [jdx#8108](jdx#8108) - **(set)** add --stdin flag for multiline environment variables by @jdx in [jdx#8110](jdx#8110) ### 🐛 Bug Fixes - **(backend)** improve conda patchelf and dependency resolution for complex packages by @jdx in [jdx#8087](jdx#8087) - **(ci)** fix validate-new-tools grep pattern for test field by @jdx in [jdx#8100](jdx#8100) - **(config)** make MISE_OFFLINE work correctly by gracefully skipping network calls by @jdx in [jdx#8109](jdx#8109) - **(github)** skip v prefix for "latest" version by @jdx in [jdx#8105](jdx#8105) - **(gitlab)** resolve tool options from config for aliased tools by @jdx in [jdx#8084](jdx#8084) - **(install)** use version_expr for Flutter to fix version resolution by @jdx in [jdx#8081](jdx#8081) - **(registry)** add Linux support for tuist by @fortmarek in [jdx#8102](jdx#8102) - **(release)** write release notes to file instead of capturing stdout by @jdx in [jdx#8086](jdx#8086) - **(upgrade)** tools are not uninstalled properly due to outdated symlink by @roele in [jdx#8099](jdx#8099) - **(upgrade)** ensure uninstallation failure does not leave invalid symlinks by @roele in [jdx#8101](jdx#8101) - SLSA for in-toto statement with no signatures by @gerhard in [jdx#8094](jdx#8094) - Vfox Plugin Auto-Installation for Environment Directives by @pose in [jdx#8035](jdx#8035) ### 📚 Documentation - use mise activate for PowerShell in getting-started by @rileychh in [jdx#8112](jdx#8112) ### 📦 Registry - add conda backend for mysql by @jdx in [jdx#8080](jdx#8080) - add conda backends for 10 asdf-only tools by @jdx in [jdx#8083](jdx#8083) - added podman-tui by @tony-sol in [jdx#8098](jdx#8098) ### Chore - sort settings.toml alphabetically and add test by @jdx in [jdx#8111](jdx#8111) ### New Contributors - @ctaintor made their first contribution in [jdx#8106](jdx#8106) - @rileychh made their first contribution in [jdx#8112](jdx#8112) - @fortmarek made their first contribution in [jdx#8102](jdx#8102) - @pose made their first contribution in [jdx#8035](jdx#8035) - @gerhard made their first contribution in [jdx#8094](jdx#8094) ## 📦 Aqua Registry Updates #### New Packages (2) - [`entireio/cli`](https://github.com/entireio/cli) - [`rmitchellscott/reManager`](https://github.com/rmitchellscott/reManager) #### Updated Packages (1) - [`atuinsh/atuin`](https://github.com/atuinsh/atuin)
Summary
MISE_OFFLINE=1causing hangs/errors — Previously, offline mode blocked all HTTP requests with hard errors (ensure!(!*env::OFFLINE, ...)), but callers didn't handle these gracefully, causing version resolution to fail instead of falling back to local data.offlineandprefer_offlineas proper settings — Now configurable viamise.toml(settings.offline = true) and documented, not just env vars.Settings::offline()andSettings::prefer_offline()convenience methods — Combine settings + env vars + CLI flags in one place, simplifying all call sites.Key behavior changes:
versions_host::list_versions()returnsOk(None)when offline/prefer-offline (falls back to local cache)versions_host::track_install()skips when offlineresolve_version()skips all remote fetching when offline, returns raw version stringlist_remote_versions_with_info()returns emptyvec![]when offline instead of making HTTP callshttp.rsensure checks useSettings::get().offline()(covers both setting and env var)Settings::prefer_offline()instead of raw env var accessCloses #6916
Test plan
mise run build— compiles successfullymise run lint-fix— all lints passmise run test:unit— 469 tests passMISE_OFFLINE=1 target/debug/mise ls— lists installed tools without errors/hangsMISE_OFFLINE=1 target/debug/mise env— outputs env vars without errors/hangsMISE_OFFLINE=1 target/debug/mise settings get offline— returnstruetarget/debug/mise settings get prefer_offline— returnsfalse🤖 Generated with Claude Code
Note
Medium Risk
Touches core version resolution and remote version listing paths to change behavior under
offline/prefer_offline, which could affect installs andls-remoteresults if the new gating is too aggressive or mis-detected.Overview
Adds new
offlineandprefer_offlinesettings (schema +settings.tomldocs/env bindings) and centralizes their evaluation viaSettings::offline()/Settings::prefer_offline().Updates multiple network/version codepaths to respect these settings: HTTP requests now block based on
Settings::offline(), remote version listing returns empty when offline, versions-host queries/telemetry and aqua registry updates are skipped when (prefer-)offline, and tool version resolution avoids remote lookups in offline mode (with new unit tests covering defaults and implications).Written by Cursor Bugbot for commit f5fb568. This will update automatically on new commits. Configure here.