Skip to content

fix(windows): resolve ERROR_UNTRUSTED_MOUNT_POINT (448) for junction and symlink working directories#9306

Open
OthmanAdi wants to merge 1 commit intowarpdotdev:masterfrom
OthmanAdi:othmanadi/fix-windows-symlink-startdir
Open

fix(windows): resolve ERROR_UNTRUSTED_MOUNT_POINT (448) for junction and symlink working directories#9306
OthmanAdi wants to merge 1 commit intowarpdotdev:masterfrom
OthmanAdi:othmanadi/fix-windows-symlink-startdir

Conversation

@OthmanAdi
Copy link
Copy Markdown

Description

Fixes #9044

On Windows, when the configured working directory (or its fallback, USERPROFILE) contains or is a junction point or reparse point, CreateProcessW fails with ERROR_UNTRUSTED_MOUNT_POINT (WinError 448). This breaks symlink traversal for the shell and all child processes, including Get-ChildItem, pytest, and any tool that resolves through junctions.

The same commands work correctly in Windows Terminal and standalone PowerShell because they pass canonicalized paths to CreateProcessW.

Root cause: In app/src/terminal/local_tty/windows/mod.rs (line 176), the start_dir is validated only with is_dir() and then passed directly as lpCurrentDirectory to CreateProcessW without canonicalization. Junction points pass the is_dir() check but fail inside the kernel's path resolution for untrusted mount points.

Fix: Call dunce::canonicalize() on both the configured start_dir and the USERPROFILE fallback before passing them to CreateProcessW. This resolves symlinks, junctions, and reparse points to their actual paths, eliminating the 448 error.

The dunce crate is already a dependency in the app crate and is used for the same purpose in working_directories.rs (line 745), available_shells.rs (lines 818, 850), standardized_path.rs (line 99), and login_item/windows.rs (line 77).

What this changes

Before After
start_dir passed raw to CreateProcessW dunce::canonicalize(start_dir) resolves junctions first
USERPROFILE fallback passed raw USERPROFILE also canonicalized
Junction directories cause error 448 Junction directories resolve to their target and work

Testing

  • cargo check -p warp passes clean
  • Manual testing on Windows 11:
    1. Create a junction: New-Item -ItemType Junction -Path "C:\Users\oasrvadmin\AppData\Local\Temp\warp_test" -Target "C:\Users\oasrvadmin\Documents"
    2. Set Warp startup directory to the junction path
    3. Before fix: CreateProcessW fails with error 448
    4. After fix: shell spawns normally, Get-ChildItem works through the junction

No new automated tests added because this fix is in the Windows ConPTY spawn path, which requires a running ConPTY session to test. The dunce::canonicalize function itself is well tested upstream.

Server API dependencies

  • N/A

Agent Mode

  • Warp Agent Mode

Changelog Entries for Stable

CHANGELOG-BUG-FIX: Fixed OS Error 448 (ERROR_UNTRUSTED_MOUNT_POINT) on Windows when the working directory contains symlink or junction points.

@cla-bot
Copy link
Copy Markdown

cla-bot Bot commented Apr 28, 2026

Thank you for your pull request and welcome to our community. We require contributors to sign our Contributor License Agreement, and we don't seem to have the users @OthmanAdi on file. In order for us to review and merge your code, each contributor must visit https://cla.warp.dev to read and agree to our CLA. Once you have done so, please comment @cla-bot check to trigger another check.

@oz-for-oss
Copy link
Copy Markdown

oz-for-oss Bot commented Apr 28, 2026

@OthmanAdi

I'm starting a first review of this pull request.

You can follow along in the session on Warp.

I approved this pull request and requested human review from: @vorporeal, @alokedesai, @zachbai.

Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).

Powered by Oz

Copy link
Copy Markdown

@oz-for-oss oz-for-oss Bot left a comment

Choose a reason for hiding this comment

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

Overview

This PR canonicalizes the Windows PTY start directory and USERPROFILE fallback before passing them to CreateProcessW, addressing failures when the configured working directory is a junction, symlink, or other reparse point.

Concerns

  • No blocking correctness, error-handling, performance, or security concerns found in the changed lines.

Verdict

Found: 0 critical, 0 important, 0 suggestions

Approve

Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).

Powered by Oz

@vorporeal
Copy link
Copy Markdown
Contributor

Hi @OthmanAdi - do you know why your commit is showing up as "unverified"? The fact that the tooltip for it says "This commit is not signed, but one or more authors requires that any commit attributed to them is signed." is concerning.

@OthmanAdi
Copy link
Copy Markdown
Author

Hey @vorporeal, thanks for catching that. I didn't have commit signing configured on this machine. Setting it up now and will push signed commits shortly.

@OthmanAdi
Copy link
Copy Markdown
Author

@cla-bot check

@cla-bot cla-bot Bot added the cla-signed label Apr 29, 2026
@cla-bot
Copy link
Copy Markdown

cla-bot Bot commented Apr 29, 2026

The cla-bot has been summoned, and re-checked this pull request!

…nctions before CreateProcessW

The start directory passed as lpCurrentDirectory to CreateProcessW was
never canonicalized. When the working directory is or contains a junction
point or reparse point, CreateProcessW fails with ERROR_UNTRUSTED_MOUNT_POINT
(WinError 448), breaking symlink traversal, pytest, and any tool that
resolves through junctions.

Resolve by calling dunce::canonicalize on both the configured start_dir
and the USERPROFILE fallback before passing them to CreateProcessW. This
resolves symlinks, junctions, and reparse points to their actual paths.

The dunce crate is already used for the same purpose elsewhere in the
codebase (working_directories.rs, available_shells.rs, standardized_path.rs).

Closes warpdotdev#9044
@OthmanAdi OthmanAdi force-pushed the othmanadi/fix-windows-symlink-startdir branch from 492de77 to 0242c1b Compare April 29, 2026 06:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

(Windows 11) OS Error 448: All symlink/junction traversal fails inside Warp

2 participants