Skip to content

fix(trust): stop printing extended-length path prefixes - #12014

Merged
jdx merged 1 commit into
jdx:mainfrom
JamBalaya56562:fix/trust-display-verbatim-path
Aug 15, 2026
Merged

jdx merged 1 commit into
jdx:mainfrom
JamBalaya56562:fix/trust-display-verbatim-path

Conversation

@JamBalaya56562

@JamBalaya56562 JamBalaya56562 commented Aug 14, 2026 •

Copy link
Copy Markdown
Contributor

mise trust canonicalizes a path before reporting it, and std::fs::canonicalize returns the
extended-length form on Windows. That form reaches the user:

> mise trust
mise trusted \\?\C:\Users\Jam\proj

> mise trust --untrust
mise untrusted \\?\C:\Users\Jam\proj
mise WARN  "\\\\?\\C:\\Users\\Jam\\proj" is trusted via settings so it will still be trusted.

The warning on the last line is the same path printed through {:?}, so Debug doubles every
backslash on top of the prefix.

mise refuses this form as input. toolset::tool_request::validate_path_string answers a
path: value beginning with it with "extended-length and device paths (\\?\, \\.\) are not
supported"
, and windows_path_separators deliberately leaves such a prefix alone rather than
rewriting it into something that "looks right and does not resolve". Handing one back in a message
offers the user a path mise itself would reject.

Scope

Measured on 2026.8.2 windows-x64: mise trust, mise trust --untrust and mise trust --ignore
each emit the prefix. trust --show, config ls, doctor, env, tasks, ls and bin-paths
emit none. Consistent with the source — the only canonicalize() results printed anywhere in the
tree are trust's three.

Two layers, and why one is not enough

PathExt::display_user is the single place mise turns a path into text for a person, and on
Windows it was to_string_lossy() — the prefix passed straight through. So the two sites in
trust.rs that already called display_path (the git-worktree warning) leaked as well. Fixing
only the call sites would not have fixed those.

It now runs the path through dunce::simplified first, which strips the prefix only when the
result still names the same file. Measured against dunce 1.0.5 rather than assumed:

\\?\C:\Users\me\proj        -> C:\Users\me\proj
C:\Users\me\proj            -> C:\Users\me\proj      (untouched)
\\server\share\proj         -> \\server\share\proj   (a real UNC path, untouched)
\\?\UNC\server\share\proj   -> unchanged             (no plain equivalent)
\\.\COM1                    -> unchanged
\\?\C:\proj\CON             -> unchanged             (reserved name)
<307-char verbatim path>    -> unchanged             (past MAX_PATH)

Those declines are the right answer: such paths do not resolve without the prefix, so simplifying
them would produce exactly the "looks right and does not resolve" string windows_path_separators
avoids.

The five trust.rs sites that bypassed display_path — three .display() and two {:?} —
now use it.

Deliberately unchanged

  • canonicalize() itself is not swapped for dunce::canonicalize(). Trust matching compares
    it against Settings::trusted_config_paths(), which canonicalizes too; both sides are verbatim
    today and agree. Changing one side's shape would break the comparison. This is a display fix only.
  • ~ substitution stays unix-only. The cfg!(unix) guard in display_user is a separate
    design decision, untouched here.
  • Verbatim UNC, device paths, reserved names and paths past MAX_PATH keep the prefix, per above.

Dependency

dunce = "1" becomes a direct dependency. dunce 1.0.5 was already in Cargo.lock — gix-discover
and others pull it in — so the only change to the lock file is one line adding it to mise's own
dependency list, and no new code is compiled. On non-Windows simplified() returns its input, so
the call needs no cfg.

Verification

Every claim above was measured on this host: the three leaking commands and the seven clean ones,
the {:?} warning, and dunce::simplified against the eight shapes listed (a small cargo probe,
the same approach used for std::env::split_paths in #12012).

Tests:

  • src/path.rs, which had no display_user tests: the drive form is simplified, and an ordinary
    path, a real UNC path, verbatim UNC, a device path and a reserved name are all left alone. The
    unix test pins the ~ substitution the refactor had to preserve.
  • e2e-win/trust_display_path.Tests.ps1: trust, --untrust and the trusted-via-settings warning
    report the path with no prefix and no doubled backslashes, while still naming the directory — so
    the assertion cannot pass by the path vanishing. It matches the prefix as a literal, since
    PowerShell's -BeLike would read the ? as a single-character wildcard.

cargo fmt was run locally. The build, clippy and the test suite were not — those are left to
CI, so behaviour after the fix rests on the measurements above and on the tests rather than on a
running binary.

Found while auditing Windows behaviour, the same pass that produced #12007, #12008, #12012 and
#12013. No existing issue or discussion covers it.

Summary by CodeRabbit

  • Bug Fixes
    • Improved Windows path display in trust, untrust, and ignore messages.
    • Removed unnecessary extended-length path prefixes for clearer output.
    • Preserved required prefixes for special and network paths.
    • Added home-directory substitution and consistent path formatting across trust warnings.

`mise trust`, `--untrust` and `--ignore` canonicalize before reporting, and
on Windows that hands back `\\?\C:\...`. mise refuses that form as *input*
-- `validate_path_string` calls extended-length and device paths unsupported
-- so reporting one offers a path mise itself would not accept. The
still-trusted-via-settings warning was worse: it printed through `{:?}`,
doubling every backslash on top of the prefix.

Two layers had to change. `PathExt::display_user` is the one place mise
turns a path into text for a person, and it passed the prefix straight
through, so even the call sites already using `display_path` leaked. It now
goes through `dunce::simplified`, which strips the prefix only when the
result still names the same file -- verbatim UNC, device paths, reserved
names and paths past MAX_PATH keep it, since those do not resolve without
it. The five trust.rs sites that bypassed `display_path` entirely now use it.

dunce 1.0.5 was already in Cargo.lock as a transitive dependency, so this
adds no new compilation.
@coderabbitai

coderabbitai Bot commented Aug 14, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 9e248fd6-6dbe-4c6f-8c29-dbb2189e2f4d

📥 Commits

Reviewing files that changed from the base of the PR and between 71212d4 and ce3da53.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (4)
  • Cargo.toml
  • e2e-win/trust_display_path.Tests.ps1
  • src/cli/trust.rs
  • src/path.rs

📝 Walkthrough

Walkthrough

The change adds dunce, simplifies safe Windows paths in display_user, updates trust command messages to use formatted paths, and adds Windows end-to-end and path regression tests.

Changes

Trust path display

Layer / File(s) Summary
Path simplification and regression coverage
Cargo.toml, src/path.rs
display_user applies dunce::simplified before rendering paths. Tests cover safe prefixes, special paths, Unix paths, and home substitution.
Trust command path formatting
src/cli/trust.rs
Trust, untrust, and ignore messages use display_path for configuration paths.
Windows end-to-end validation
e2e-win/trust_display_path.Tests.ps1
Tests verify simplified paths in trusted, untrusted, and settings-trusted output.

Estimated code review effort: 2 (Simple) | ~10 minutes

Merge Risk: ⚪ Minimal · up to ce3da

The change is a localized Windows path-display fix with no actionable merge-blocking risk remaining beyond normal checks and review.

Suggested reviewers: jdx

Poem

A rabbit hops where trust paths gleam,
Safe prefixes fade like a dream.
Trust and untrust speak clear and bright,
Tests guard each Windows path right.
“Carrots for dunce!” the rabbit sings.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: removing extended-length path prefixes from mise trust output.

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@JamBalaya56562
JamBalaya56562 marked this pull request as ready for review August 15, 2026 01:58
@greptile-apps

greptile-apps Bot commented Aug 15, 2026 •

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR normalizes user-facing Windows paths without changing the canonical paths used for trust matching.

  • Adds dunce as a direct dependency for conservative extended-length path simplification.
  • Routes trust, untrust, ignore, and settings-warning output through the shared path formatter.
  • Adds Windows end-to-end coverage and platform-specific unit tests for preserved and simplified path forms.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains.

Important Files Changed

Filename Overview
src/path.rs Applies conservative Windows path simplification in the shared user-facing formatter while preserving Unix home substitution.
src/cli/trust.rs Routes canonical trust-path messages and warnings through the shared display formatter.
e2e-win/trust_display_path.Tests.ps1 Verifies that trust output removes simplifiable prefixes without dropping paths or retaining debug escaping.
Cargo.toml Promotes the already-resolved dunce crate to a direct dependency.
Cargo.lock Records dunce in mise’s direct dependency list without changing its locked version.

Reviews (2): Last reviewed commit: "fix(trust): stop printing extended-lengt..." | Re-trigger Greptile

@JamBalaya56562
JamBalaya56562 marked this pull request as draft August 15, 2026 02:15
@JamBalaya56562
JamBalaya56562 marked this pull request as ready for review August 15, 2026 02:24
@jdx
jdx merged commit 0742b33 into jdx:main Aug 15, 2026
30 checks passed
@JamBalaya56562
JamBalaya56562 deleted the fix/trust-display-verbatim-path branch August 15, 2026 06:13
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.

2 participants