Installed is not working
A PC can have Rust and still be unable to build a Rust program. Here is what an agent did when it found that out halfway through a task, and what QuorX checks now before the agent starts.
Someone asks an agent to write a small Rust program, build it and run it. The computer has Rust: cargo --version answers, rustc --version answers. The agent writes the code, runs cargo build, and gets this:
> cargo build 2>&1 | Select-Object -Last 30 Compiling wc-lite v0.1.0 error: linker `link.exe` not found | = note: program not found note: the msvc targets depend on the msvc linker but `link.exe` was not found note: please ensure that Visual Studio 2017 or later, or Build Tools for Visual Studio were installed with the Visual C++ option note: VS Code is a different product, and is not sufficient error: could not compile `wc-lite` (bin "wc-lite") due to 1 previous error >
Rust compiles the code itself, but on Windows it hands the last step, linking, to Microsoft's linker. That linker comes with Visual Studio or its Build Tools, and only when the C++ part is ticked. A computer can have a complete, current Rust install and no linker at all. The Windows PC the runs below come from was exactly that computer.
This article is about that gap between "the tool is installed" and "the tool can do the job", what it costs an agent to find the gap by itself, and what QuorX does about it now.
What the agent did without help
QuorX has a UI test (npm run test:ui) that drives the desktop app like a person would. One of its scenarios asks the agent for exactly this task: a Rust program called wc-lite that counts lines, words and bytes, built and then run on its own Cargo.toml. The test answers each approval card like a careful user: it allows builds and reads, and refuses installs for the whole computer.
On 20 October at 00:55 IST, before QuorX checked toolchains by building anything, the agent (DeepSeek V4.1 Flash) hit the linker error on its first build and then went looking for a way around it. This is what it ran, from the run's own log:
> rustup toolchain list; rustup target list --installed stable-x86_64-pc-windows-msvc (active, default) x86_64-pc-windows-msvc > Get-ChildItem "C:\Program Files (x86)\Microsoft Visual Studio"; where.exe link.exe gcc.exe lld-link.exe clang.exe (nothing found, exit code 1) > Get-ChildItem "C:\Program Files (x86)\Windows Kits"; Get-ChildItem C:\ -Directory -Filter "*mingw*" (nothing found) > rustc --version --verbose rustc 1.97.1 (8bab26f4f 2026-07-14) host: x86_64-pc-windows-msvc > rustup target add x86_64-pc-windows-gnu 2>&1 | Select-Object -Last 6 Tripwire: 25 files vanished outside the project within 3s, so QuorX stopped "rustup target add x86_64-pc-windows-gnu". > $c=@("C:\msys64\mingw64\bin", "C:\Program Files\LLVM\bin", "C:\Program Files\Git\usr\bin", …); foreach ($p in $c) { … } absent C:\msys64\mingw64\bin absent C:\Program Files\LLVM\bin FOUND in C:\Program Files\Git\usr\bin C:\Program Files\Git\usr\bin\link.exe > cargo build 2>&1 | Select-Object -Last 6 note: please ensure that Visual Studio 2017 or later, or Build Tools for Visual Studio were installed with the Visual C++ option note: VS Code is a different product, and is not sufficient error: could not compile `wc-lite` (bin "wc-lite") due to 1 previous error >
Eleven commands in all. Some of them are reasonable: look for Visual Studio, look for MinGW, check which toolchain is active. Two of them show how a search like this goes wrong.
- It asked for an install that changes the whole computer.
rustup target add x86_64-pc-windows-gnudownloads a second Rust target into the user's profile. At the time the rules filed it as an install without marking it as one for the whole computer, so the card looked like an ordinary step. While it ran, rustup unpacked and deleted 25 files in its own temp folder within 3 seconds, and QuorX's tripwire stopped it. That was a false alarm, and it is part of the story in Stop means stop. - It found the wrong
link.exe. Git for Windows ships alink.exeinC:\Program Files\Git\usr\bin. It is the Unixlinkcommand, which makes hard links between files. It has nothing to do with linking programs. An agent that sees "FOUND link.exe" and puts that folder first on its PATH has made the problem harder to read.
The agent did end honestly: its last plan item says the build is blocked on the missing linker. The test still failed, because the test asked for a built program and there wasn't one. The run took 140 seconds and $0.0045, according to its line in the test's logs/runs.jsonl.
Why an agent can't skip this check
A person who sets up their own PC knows what they installed. An agent arrives cold. It has two cheap ways to learn what a computer has, and both mislead in the same direction:
- Version commands.
cargo --versionproves cargo starts. It says nothing about the linker, the SDK, a licence that hasn't been accepted, or a workload that is half installed. - Its own training. "Rust on Windows needs the MSVC Build Tools" is common knowledge. Whether this computer has them is not.
So the agent finds out the expensive way: by trying to build, failing, and then searching. Each search is a command the user has to read on an approval card. Each guess risks an install the user didn't ask for. The longer the hunt, the more likely the agent settles on a workaround, such as a different toolchain or a wrapper script, which leaves the project in a state the user didn't choose.
There is a second reason to check up front. When the agent knows from the start, it can tell the user before it writes any code, and the user can choose: install the Build Tools, accept a checked but unbuilt crate, or use a different language.
What QuorX does now
QuorX now checks Rust by building a tiny program. The Rust pack (server/packs/rust.js) writes fn main() {} to a temporary folder, runs rustc on it, and looks for the resulting main.exe. If there is no program and the output mentions the linker, the toolchain is marked "installed, but it can't build programs here", with the reason.
The result goes two places.
- Into the agent's notes for every reply. For a broken toolchain the note reads, in part: "Rust (cargo): no C linker … Checking code still works (cargo check …), but building or running a program won't: before you try, tell the user." It then lists the options in order: install the Build Tools from the Setup check, let the agent run the Build Tools install (which asks first and shows Windows' admin prompt), use the GNU toolchain for this folder only, or stop at a checked crate.
- Into ⚙ Settings → Setup check, where the Rust row says what is wrong and offers the install, with the C++ workload included.
Here is the same task, before and after the check, from the two UI test runs on this PC:
- 1Knows before it startsIts plan, 14 seconds in: "this machine has Rust but no C linker (no MSVC Build Tools), so linking may fail".
- 2Writes the crateSame program, std only.
- 3Tries once, then tries rust-lldTwo build attempts with the linker bundled in Rust. Both fail.
- 4Asks for the GNU targetThis time the card says it installs for the whole computer. The test refuses it.
- 5Checks its counting another wayA Python script ports its counting code and compares it with a second implementation on tricky inputs.
- 6Says so plainly"The crate is written, but I could not build or run it here: this machine has Rust with no C linker."
18 of 18 steps. The pass condition on a PC like this is the agent saying it can't link, with the reason.
Be careful with the comparison. The runs cost about the same ($0.0045 and $0.0043) and took about the same time (140 and 144 seconds). The agent still tried to build, twice more than it needed to. What changed is where it started from and what the user saw: one install card instead of a disk search, and that card named the install for what it was.
How the program finally got built
A QuorX chat on a Windows PC met the same problem, with a user who wanted a working program. Rust 1.97.1 compiled, and there was no link.exe, gcc or clang. The chat used DeepSeek V4.1 Flash and took three replies. The numbers are from that chat's run logs:
| Reply | What happened | Model calls | Commands | Minutes | Cost |
|---|---|---|---|---|---|
| 1 | Checked the toolchain, found no C linker, wrote the crate, ran cargo check, then asked how to get a linker: the GNU toolchain through rustup, the Build Tools with C++, or "I'll install it myself" | 15 | 6 | 1.3 | $0.0092 |
| 2 | Installed the GNU toolchain (rustup toolchain install stable-x86_64-pc-windows-gnu --profile minimal) as a background job the user approved, and pinned it to this folder only with a rust-toolchain.toml | 28 | 10 | 6.7 | $0.0202 |
| 3 | cargo build --release, the tests, and a run on its own files | 20 | 6 | 5.6 | $0.0099 |
| All | 63 | 22 | 13.6 | $0.0393 |
The GNU toolchain is the third option QuorX's notes offer for a PC like this: it makes this one folder build and leaves the rest of the computer as it was. It doesn't fit every project. Tauri's dependencies, for one, need an assembler that the GNU toolchain doesn't ship, so for those the notes offer only the Build Tools.
The program it built is target\release\wc-lite.exe, about 1.2 MB. Run outside QuorX afterwards, in the chat's folder (named Rust-Test), it prints:
> .\target\release\wc-lite.exe Cargo.toml src\main.rs 16 44 290 Cargo.toml 528 1933 16607 src\main.rs 544 1977 16897 total > .\target\release\wc-lite.exe -l Cargo.toml 16 Cargo.toml >
The build output itself isn't in the run logs we have, so it isn't shown here. The program exists and runs, and that is the evidence.
That part of the story is in Agents route around guardrails.
Rust was only the first
The same idea now runs through QuorX's platform packs. A pack's toolchain can carry a works() check that does the smallest real job; a version query alone proves too little. At the merge of the pack framework (PR #3) one toolchain had such a check: Rust. Today ten of the 33 toolchains the packs know have one:
| Toolchain | What "works" means |
|---|---|
| Rust | builds an empty program (needs a C linker) |
| .NET SDK | builds something: a broken workload or a global.json pinning a missing SDK only shows up then |
| Java (JDK) | compiles and runs a tiny program: a Java runtime without the JDK has no javac |
| Tauri CLI | works only where Rust can link, so it asks the Rust check |
| Godot 4 | starts and parses a script (a Godot 3 editor fails here) |
| WiX Toolset | builds a tiny package (WiX 7 refuses until its licence is accepted) |
| Xcode | is ready: the right developer folder, licence accepted, first launch done |
| Android SDK | has a platform and build-tools installed |
| Android emulator | has at least one virtual device to start |
| LLDB (lldb-dap) | the debug adapter starts and answers --help |
Counts are from allToolchains() in server/packs/index.js at commit 0174105 (the PR #3 merge) and at today's main.
What to take from this
For anyone building agents: a version string is a weak signal. Prove the toolchain does the smallest real job, tell the model the result before it plans, and tell it what still works, so it has a useful fallback instead of a search.
For anyone using QuorX: ⚙ Settings → Setup check is worth opening once on a new PC. A toolchain marked "can't build here" costs a confused first reply if it isn't fixed first.