Repository navigation
fix(semver): stop calling a mangled value a semver range - #11949
Conversation
A tool version broken before it reached mise was reported as an unsupported
semver range, which points the reader at versions when the value itself is
what is wrong:
mise WARN semver range "path:C:<TAB>ools<LF>ode" is not supported for
node (source: .../mise.toml); use a concrete version or
version prefix
mise ERROR invalid tool path "C:\tools\node": contains forbidden
character '\t'
The error underneath already names the real cause. The warning above it does
not, and it comes first.
TOML reads `\t` as a tab and `\n` as a newline inside a basic string, so
`path = "C:\tools\node"` arrives here with control characters in it.
`is_npm_semver_range_query` then hits `split_whitespace().count() > 1`, which
counts those as separators, and calls the value a multi-part range.
A real npm range never contains a control character, so skipping such values
in the predicate separates the two cases cleanly. Range detection is
unchanged for `^1.2.3`, `>=1.0 <2.0`, `1.x`, `*`, `1.2 - 1.5` and
`1.0 || 2.0`, and a value with a control character is still rejected by the
validation that follows.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository YAML (base), Central YAML (inherited), Organization UI (inherited) Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughThe semver query classifier now rejects control characters before range detection. Unit tests cover malformed and valid queries. An end-to-end test verifies escaped Windows-style paths fail as invalid paths without semver-range warnings. ChangesSemver detection hardening
Estimated code review effort: 3 (Moderate) | ~20 minutes Mergeability Score: ⚪ Minimal · up to The change only prevents malformed values containing control characters from being mislabeled as semver ranges while preserving validation errors and real range detection; no actionable merge-blocking risk remains after normal checks and review. Possibly related PRs
Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Greptile SummaryThe PR prevents malformed tool values containing control characters from being mislabeled as unsupported semantic-version ranges.
Confidence Score: 5/5The PR appears safe to merge, with the malformed values still rejected by existing validation while the misleading warning is suppressed. The new predicate guard only changes diagnostic range classification for control-character-containing values, and the added unit and end-to-end coverage preserves genuine range detection and confirms that invalid paths still fail. Important Files Changed
Reviews (1): Last reviewed commit: "fix(semver): stop calling a mangled valu..." | Re-trigger Greptile |
A tool version that was mangled before it reached mise gets reported as an unsupported semver
range, which sends the reader looking at versions when the value itself is what is wrong.
The problem
Measured on 2026.8.2 windows-x64, with
node = { path = "C:\tools\node" }inmise.toml:The error is already right. The warning above it is not, and it is what a reader sees first —
so the advice they act on is "use a concrete version", which has nothing to do with the problem.
TOML reads
\tas a tab and\nas a newline inside a basic (double-quoted) string, so thevalue arrives here with control characters embedded. That is easy to write by accident on Windows;
#11937 documents the quoting side of it.
Why it is detected as a range
is_npm_semver_range_queryends with:split_whitespacecounts tabs and newlines as separators, sopath:C:<TAB>ools<LF>odelooks likea multi-part range. Confirmed with a standalone
rustcprobe of the predicate:A real npm range never contains a control character. That is what makes the two cases
separable rather than a judgement call.
The change
One early return in the predicate:
Fixed in
is_npm_semver_range_queryrather than at the call site intool_request.rs, becausethe predicate answers "is this npm range syntax?" and returning
truefor a string with controlcharacters in it is wrong by that contract — any other caller would inherit the same mistake.
What does not change
^1.2.3,>=1.0 <2.0,1.x,*,1.2 - 1.5,1.0 || 2.0— none containa control character.
validate_version_stringandvalidate_path_stringboth rejectcharacters below
0x20, so suppressing the warning does not let anything through; it just stopsthe misleading line from preceding the accurate one.
invalid tool path …: contains forbidden character '\t'error is untouched.Tests
src/semver.rs's existing test module: tab/newline values are not ranges(including the
path:C:\tools\nodecase), with a control asserting the six range forms aboveare still detected and that ordinary values —
1.0.0,latest, and a well-formedpath:C:/tools/node— stay non-ranges. Without that control this could pass by disabling rangedetection entirely.
e2e/config/test_semver_range_warningalready covered the warning firing for realranges; it now also covers a mangled value producing
invalid tool pathand nosemver rangeline.mise lsexits non-zero for that config, so those two assertions use the failurehelpers rather than
assert_contains, which treats a non-zero status as the test failing.Not run
cargo fmt --alland a standalonerustcprobe of the predicate covering every assertion the newunit tests make (0 failures); no full local build. The transcript above is from a released binary
reproducing the bug. CI is what exercises the fix.
Found while working on #11937, and split out of it as a separate concern.
Summary by CodeRabbit