fix: filter empty segments in colon-separated env var parsing#9076
fix: filter empty segments in colon-separated env var parsing#9076
Conversation
There was a problem hiding this comment.
Code Review
This pull request addresses a potential panic when environment variables like MISE_OVERRIDE_CONFIG_FILENAMES are set to empty strings or contain empty segments. The fix involves filtering out empty strings after splitting by colons in src/env.rs. Additionally, a new e2e regression test and a unit test have been added to ensure correct behavior for various edge cases. I have no feedback to provide.
Greptile SummaryThis PR fixes a panic in Confidence Score: 5/5Safe to merge — the fix is minimal, correct, and well-tested; no P0/P1 issues found. The panic fix is verified by tracing from No files require special attention. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A["env var set? (e.g. MISE_OVERRIDE_CONFIG_FILENAMES)"] -->|"Err (unset)"| B["miserc fallback / unwrap_or_default\n→ empty IndexSet"]
A -->|"Ok(v) == 'none'"| C["Some(empty IndexSet)"]
A -->|"Ok(v)"| D["split_colon_list(v)"]
D --> E["split(':')"]
E --> F["filter empty segments"]
F --> G["collect → IndexSet"]
G --> H{{"is_empty()?"}}
B --> H
H -->|"true"| I["use default config filenames\n(.config/mise/config.toml, mise.toml, …)"]
H -->|"false"| J["use override filenames only"]
Reviews (4): Last reviewed commit: "[autofix.ci] apply automated fixes" | Re-trigger Greptile |
7fe9e8e to
7ae76d1
Compare
7ae76d1 to
4414ec2
Compare
When MISE_OVERRIDE_CONFIG_FILENAMES is set to an empty string,
split(':') produces [""] — a set containing one empty string.
This non-empty set replaces the default config filename list,
injecting "" as a config path. During Config::load, this empty
path reaches config_root() which panics on path.parent().unwrap()
because the absolutized empty string resolves to the filesystem
root (/).
The e2e test reproduces the exact panic seen in CI when vfox
plugins spawn nested mise processes that inherit the parent's
MISE_OVERRIDE_CONFIG_FILENAMES.
Also adds a unit test documenting the correct filter pattern.
MISE_OVERRIDE_CONFIG_FILENAMES and MISE_OVERRIDE_TOOL_VERSIONS_FILENAMES
split their values on ':' but don't filter empty segments. When set to
an empty string (e.g., by a parent process clearing it via VAR='' cmd),
split(':') produces [""] — a one-element set containing an empty string.
This non-empty set replaces the default config filename list and injects
"" as a config path. During Config::load, the empty path absolutizes to
the filesystem root, which has no parent directory, causing config_root()
to panic on path.parent().unwrap().
Extract split_colon_list() helper that filters empty segments. Both env
vars now use it. Also handles trailing/leading colons and consecutive
colons gracefully.
4414ec2 to
f085403
Compare
### 🚀 Features - **(npm)** use --min-release-age for npm 11.10.0+ supply chain protection by @webkaz in [#9072](#9072) - **(registry)** add openfga by @mnm364 in [#9084](#9084) - **(task)** allow to set confirmation default by @roele in [#9089](#9089) - support os/arch compound syntax in tool os filtering by @RobertDeRose in [#9088](#9088) ### 🐛 Bug Fixes - **(activate)** export __MISE_EXE and resolve bare ARGV0 to absolute path by @fru1tworld in [#9081](#9081) - **(install)** support aliased installs sharing a backend by @jdx in [#9093](#9093) - **(shim)** use which_no_shims when resolving mise binary in reshim and doctor by @kevinswiber in [#9071](#9071) - filter empty segments in colon-separated env var parsing by @baby-joel in [#9076](#9076) ### 📚 Documentation - fix wrong file reference to forgejo backend implemenation by @roele in [#9090](#9090) - fix cli token command for token resolution by @roele in [#9077](#9077) ### 📦 Registry - add trzsz-go ([aqua:trzsz/trzsz-go](https://github.com/trzsz/trzsz-go)) by @ZeroAurora in [#9083](#9083) - add copilot ([aqua:github/copilot-cli](https://github.com/github/copilot-cli)) by @risu729 in [#9082](#9082) ### Chore - add AGENTS.md symlink by @jdx in [#9094](#9094) ### New Contributors - @kevinswiber made their first contribution in [#9071](#9071) - @webkaz made their first contribution in [#9072](#9072) - @RobertDeRose made their first contribution in [#9088](#9088) ## 📦 Aqua Registry Updates #### New Packages (7) - [`IBM-Cloud/ibm-cloud-cli-release`](https://github.com/IBM-Cloud/ibm-cloud-cli-release) - [`max-sixty/worktrunk`](https://github.com/max-sixty/worktrunk) - [`micelio.dev/hif`](https://github.com/micelio.dev/hif) - [`pgplex/pgschema`](https://github.com/pgplex/pgschema) - [`rose-pine/rose-pine-bloom`](https://github.com/rose-pine/rose-pine-bloom) - [`santosr2/TerraTidy`](https://github.com/santosr2/TerraTidy) - [`trzsz/trzsz-go`](https://github.com/trzsz/trzsz-go) #### Updated Packages (3) - [`mvdan/sh`](https://github.com/mvdan/sh) - [`rvben/rumdl`](https://github.com/rvben/rumdl) - [`temporalio/temporal`](https://github.com/temporalio/temporal)
## [2026.4.14](https://github.com/jdx/mise/compare/v2026.4.13..v2026.4.14) - 2026-04-15 ### Chore - bump sigstore-verification by @jdx in [#9128](jdx/mise#9128) ## [2026.4.13](https://github.com/jdx/mise/compare/v2026.4.12..v2026.4.13) - 2026-04-15 ### 🐛 Bug Fixes - **(go)** honor install_before for module versions by @mariusvniekerk in [#9097](jdx/mise#9097) - **(vfox-plugin)** support Git URL with commit hash for mise.toml by @Oyami-Srk in [#9099](jdx/mise#9099) - `MISE_FETCH_REMOTE_VERSIONS_CACHE` not respected by @mcncl in [#9096](jdx/mise#9096) ### 📦️ Dependency Updates - unblock cargo-deny advisories check by @jdx in [#9112](jdx/mise#9112) ### New Contributors - @mariusvniekerk made their first contribution in [#9097](jdx/mise#9097) - @mcncl made their first contribution in [#9096](jdx/mise#9096) - @Oyami-Srk made their first contribution in [#9099](jdx/mise#9099) ## [2026.4.12](https://github.com/jdx/mise/compare/v2026.4.11..v2026.4.12) - 2026-04-15 ### 🚀 Features - **(npm)** use --min-release-age for npm 11.10.0+ supply chain protection by @webkaz in [#9072](jdx/mise#9072) - **(registry)** add openfga by @mnm364 in [#9084](jdx/mise#9084) - **(task)** allow to set confirmation default by @roele in [#9089](jdx/mise#9089) - support os/arch compound syntax in tool os filtering by @RobertDeRose in [#9088](jdx/mise#9088) ### 🐛 Bug Fixes - **(activate)** export __MISE_EXE and resolve bare ARGV0 to absolute path by @fru1tworld in [#9081](jdx/mise#9081) - **(install)** support aliased installs sharing a backend by @jdx in [#9093](jdx/mise#9093) - **(shim)** use which_no_shims when resolving mise binary in reshim and doctor by @kevinswiber in [#9071](jdx/mise#9071) - filter empty segments in colon-separated env var parsing by @baby-joel in [#9076](jdx/mise#9076) ### 📚 Documentation - fix wrong file reference to forgejo backend implemenation by @roele in [#9090](jdx/mise#9090) - fix cli token command for token resolution by @roele in [#9077](jdx/mise#9077)
Problem
MISE_OVERRIDE_CONFIG_FILENAMES=""\(empty string) causes mise to panic:When the env var is set to an empty string,
split(':')produces[""]— a set with one empty-string entry. This non-empty set replaces the default config filename list, injecting""as a config path. DuringConfig::load, the empty path absolutizes to the filesystem root (/), which has no parent directory, causingconfig_root()to panic onpath.parent().unwrap().How this happens in practice
vfox plugins that spawn nested mise processes (e.g.,
mise -C <plugin-path> run install) inherit the parent'sMISE_OVERRIDE_CONFIG_FILENAMES. When the parent sets it tomise.ci.toml, the child process looks for a non-existentmise.ci.tomlin the plugin directory. Unsetting it viaVAR='' commandis a common workaround — but the empty string triggers this panic.Fix
Add
.filter(|s| !s.is_empty())to both colon-split expressions insrc/env.rs:MISE_OVERRIDE_CONFIG_FILENAMESMISE_OVERRIDE_TOOL_VERSIONS_FILENAMESThis also correctly handles edge cases like trailing/leading colons (
:mise.ci.toml:) and consecutive colons.Tests
test_override_config_filenames_empty— verifies empty string, colon-only, and leading/trailing colons all work without panickingtest_split_colon_filters_empty_segments— documents the correct filter pattern for all edge cases