Skip to content

Windows Bugs We Fixed

github-actions[bot] edited this page Oct 18, 2026 · 2 revisions

The bugs the Windows CI job found, why they happened and how we fixed them. How Windows support works is on Windows Support.

Local History refused every file on Windows. check_file_path wanted the path to start with /, so a C:/... path was "invalid" and no snapshot was ever written. The Windows CI run showed it. Now paths::after_root accepts / or, on Windows, a drive root, and the rest of the check is unchanged, so . and .. parts are still refused.

A rooted path could leave the work tree on Windows. safe_join and the submodule path check refused absolute paths with is_absolute(). On Windows \etc\passwd has a root but no drive, so it is not "absolute", and joining it onto the repository gives a path at the drive root. Both checks now also refuse Component::RootDir, like the MCP path check already did.

The installer check hung for hours. The first windows-installer.yml run built the installer, then sat in "Install it and run the command line program" until it was cancelled. The step runs in Git Bash, which rewrites arguments that look like Unix paths: /S became S:/, so the installer did not run silently and waited for a click on a screen nobody sees. The step now sets MSYS_NO_PATHCONV=1, which passes arguments through unchanged, and has a 10 minute limit (60 for the job), so any other hang fails fast instead of running until GitHub's 6 hour limit.

A repository made in an admin terminal was "Not a git repository". Found in the manual test on a Windows 11 PC. A repository cloned or created in an elevated terminal belongs to the Administrators group. Git accepts it when the user is in that group, even without elevation, but libgit2, which the app uses for reads, only accepts it from an elevated program. The app runs without elevation, so every read failed while git status worked. git::repo::configure_libgit2 turns off libgit2's ownership check on Windows at start (the test sandbox does the same). We chose this over a "take ownership" message because the check guards against running programs a repository's config names, and libgit2 runs none here; every write goes through git, which keeps its own check with the right Windows rules.

Shortcut labels said Cmd on Windows. Found in the first Windows screenshot: the empty editor area showed "Shift+Cmd+G" and "Cmd+P", and about 40 tooltips, buttons and Settings hints did the same. They were typed as text, so neither the platform nor custom shortcuts changed them. Now they ask the registry (commandKeys, withCommandKeys, localKeys), which knows the real keys on each platform, Alt+Home for the Navigation Bar included. Writing words on macOS too (formatKeyWords) kept the macOS labels exactly as they were.

Terminal paths printed with backslashes did not link, and other letter case missed the workspace. Windows tools print C:\Users\me\repo\src\app.ts:12, and some print the drive or folders in lower case. The link finder only knew / paths, and the path helpers compared case exactly, so neither became a link. Printed paths now go through fromNativePath, the path helpers ignore case on Windows, and real_files returns each file's real path, so the link opens the existing tab instead of a second one in other case.

Keep computer awake did not build on Windows. The Windows CI job stopped with "variant Process is never constructed". keep_awake.rs holds the computer awake with a child process on macOS (caffeinate) and Linux (systemd-inhibit), but with a thread on Windows, so the Guard::Process variant was never made there and clippy's -D warnings turned that into an error. The variant and its match arms are now built only off Windows (#[cfg(not(windows))]), like the Thread variant is built only on Windows, so each system compiles just the guard it uses.

The memory log test failed on the Windows runner and stopped a beta. The beta.12 release's CI failed in memory_log::tests::logs_changes_and_events_then_stops: the log ended with readings but no "memory log stopped" line. The test turned the log off and read the file after a fixed 250 ms, but the logger thread writes its last line only after the memory reading it is taking, and on a busy Windows runner that reading took longer. The app was fine; the wait was too short. The test now reads the log until it ends with the stop line (at most 10 seconds) instead of sleeping a fixed time, so a slow machine only makes it wait longer.

Home

Using Nibtree

Developers

How features work

Clone this wiki locally