Report why a cleanup command could not start - #121
Merged
AmirMS (AmelBawa-msft) merged 1 commit intoSep 29, 2026
Merged
Conversation
Invoke-DevConfigNativeCommand runs a bounded command in a separate runspace. When the executable cannot start at all, the failure lands in that runspace's error stream, which nothing read: the function returned ExitCode $null and Output $null, and Invoke-DevConfigCleanupCommand then failed on $null.Trim() with "You cannot call a method on a null-valued expression." instead of the reason. The in-process path (TimeoutSeconds 0) surfaced the real error. Surface the runspace error the same way, and build the failure message from a string so a missing output cannot mask the exit code.
There was a problem hiding this comment.
Copilot review overview
🟢 Approval recommended
The focused changes address the reported failure without an identified regression.
Review effort: Balanced
Findings: None
What changed in this PR
This PR makes Windows Dev Config cleanup report why a command could not start instead of showing a null-value error.
Changes:
- Throws the first error captured by the bounded command’s runspace.
- Safely formats cleanup output when it is null.
| File | Description |
|---|---|
src/windows-dev-config/steps/_environment.ps1 |
Surfaces command-start errors and handles null cleanup output. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
AmirMS (AmelBawa-msft)
approved these changes
Sep 29, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
I read through the new Uninstall code from #108 before trying it on my own machines; this is one of three small things I found there (the other two are separate PRs).
Invoke-DevConfigNativeCommandruns a bounded command in a separate runspace. When the executable cannot start at all, the error lands in the runspace's error stream, which is not read, and the function returnsExitCodeandOutputboth$null.Invoke-DevConfigCleanupCommandthen fails on$result.Output.Trim(), so the user seesinstead of the reason. Every cleanup call takes this path (
-TimeoutSecondsdefaults to 900), and the per-user task script embeds the same function, so it loses the reason too. The in-process path (-TimeoutSeconds 0) already surfaces the real error.The fix throws the first error from the runspace's error stream after
EndInvoke, the same exception the in-process path throws, and builds the failure message from[string]$result.Output.Checked before and after on Windows 11 Pro 25H2 (build 26200.9550), in pwsh 7.6.6 and in Windows PowerShell 5.1.26100 (the cleanup host), by dot-sourcing
_environment.ps1and callingInvoke-DevConfigCleanupCommand -FilePath <path>\unins000.exe -TimeoutSeconds 30against a text file of that name: before,ExitCode=$nulland the null-method message; after,Program 'unins000.exe' failed to run: ... not a valid application for this OS platform. A command that exits 7 still reportsfailed (7): boom, and a successful one still returnsExitCode=0.Only
src/is touched; the signed copy is left to the sign pipeline.Thanks for having a look.