Repository navigation
fix(desktop): retry a timed-out Windows update signature check once - #21273
juliusmarminge merged 6 commits into
Conversation
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
electron-updater runs Get-AuthenticodeSignature with a 20 s limit after a Windows download. Endpoint security scanning the new installer can push the first check past that, so the download fails even though the signature is valid. Retry the same check once when it was killed by the timeout. A rejected signature or any other failure is returned unchanged. Fixes pingdotgg#20345 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ater skipped When a signature check fails and its PowerShell capability probe also fails, electron-updater logs that it is ignoring signature validation and resolves null, which NsisUpdater accepts. The first check keeps that upstream behavior. The retry runs only after a timed-out check, so it now returns a rejection when it sees that warning or any result other than a rejection string or a clean null. Also cover a verifier reused across downloads, so the retry wrapper does not stack. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ApprovabilityVerdict: Needs Human Approval Macroscope's review found this PR requires human approval — This production change wraps Windows update code-signature verification, retries timeout-killed PowerShell checks, and adds fail-closed handling for skipped validation. Because it changes a security-sensitive update-integrity boundary on an existing download path, human review is warranted despite the focused scope and targeted tests. You can add or adjust custom eligibility rules. Learn more. |
|
Warning Review limit reachedOnly developers with an assigned seat can use this organization's usage-based review budget, and seats here are assigned manually. Ask an admin to assign a seat, or change the review continuation mode in Billing. Next included review available in 12 minutes. View limit details
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info
📝 Walkthrough
Merge Risk: ⚪ Minimal · up to
|
…ate-signature-retry
|
Taking over this one as maintainer for batch desktop-app-06. I’ll preserve the contributor commits, merge current main, reduce the tests, and independently review the timeout retry and signature failure behavior. Real Windows updater verification and human approval remain required; this batch will not merge it. |
|
Reverting this in #22222 together with the other desktop fixes the takeover campaign merged yesterday. Nothing was wrong with the review of this change; it was merged on CI and code audits only, and after #20907 from the same batch broke existing installs the maintainer decided that desktop changes do not ship without being run on a real desktop build. To bring it back: open a fresh PR from the original commit, run it on a real build that already has user state on each platform it touches, and put the before/after proof in the body. |
…ingdotgg#21273) Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: Julius Marminge <julius0216@outlook.com> (cherry picked from commit 3698269)
Problem
Windows updates can fail at 100% when electron-updater's PowerShell
Get-AuthenticodeSignaturecheck exceeds 20 seconds. Endpoint security scanning the new installer can cause that timeout. The reporter in #20345 reran the same command on the same file and it passed in 4.2 seconds.Change
Wrap the Windows NSIS updater's verifier before downloading. The first check is unchanged from upstream. Retry once if it rejects with
killed === true, Node's timeout-kill error shape, using the same verifier, publisher names and installer path.electron-updater 6.8.9 returns
nullboth for a valid signature and when its PowerShell capability probe fails and it skips validation, logging "Ignoring signature validation". During the retry, a forwarding logger detects that warning, then the original logger is restored. A skipped retry fails closed. A cleannullpasses; signature or publisher rejection, other errors and a second timeout still fail. The first check's upstream skip behavior is unchanged. There is no checksum-only fallback added by this PR.A WeakSet prevents stacked wrappers on repeat downloads. macOS and Linux lack this verifier property. The change is 57 non-test lines, 147 total.
Scope and approval
Grok's October 16 triage on behalf of Julius accepted #20345 as a bug. It left the direction open between retrying after a timeout and in-process verification. This PR takes the retry option; no maintainer has agreed to this implementation. In-process verification and clearer timeout reporting remain separate work.
Prior PRs: none found on this issue, open or closed. No code is reused from another PR.
Verification
The following Linux checks are retained from the held verification record; this Windows run did not rerun them.
From
apps/desktop, with a stand-in NSIS verifier:The original tests on main
3ff5b3c82a, test commit1c1a24d0e6, give 2 failures and 5 passes. With the new tests onbadd70c9e5, the skipped-retry regression fails, 8 pass. At6ea17522cb, all 9 pass; the suite passes 100 tests across 7 files. Removing the WeakSet guard makes the reused-verifier test fail with 6 calls instead of 4.Changed-file
vp lintandvp fmt --check, desktoptsc-rs --noEmitandvp run knip:checkpassed in that held record.The held record also includes a standalone Linux x64 Node v24.22.0 check using a 2-second
execFilelimit and a 5-second stand-in command. The actual Linux timeout reportskilled=true,SIGTERM, null exit code and empty stderr; an exit-1 failure reportskilled=falseand does not match the retry. This checks Node error shape on Linux, not PowerShell behavior on Windows.On October 18, 2026, a real Windows 11 Enterprise Evaluation VM booted, accepted login and returned guest-agent preflight results for Windows build 26300, PowerShell 5.1, Node v24.22.0, pnpm 11.10.0 and Vite+ 1.3.0. The host candidate worktree was clean at
6ea17522cb4648a6df730e90494b5721bc42a1ff.The real Win11 x64 unsigned NSIS build of
6ea17522cb4648a6df730e90494b5721bc42a1ffsucceeded with version0.1.1-local.21273. A second unsigned NSIS package, version0.1.2, reused that build with the supported--skip-build --mock-updatesroute. Both artifact commands exited 0. The original dependency installation succeeded; its first artifact attempt failed for missing toolchain prerequisites, which were then installed before the successful artifact retry.The candidate app was installed and launched in the VM. Its real electron-updater flow found and downloaded
0.1.2from the repository'sscripts/mock-update-server.tsrunning on guest localhost port 31273. The old blockmap returned 404, so electron-updater fell back to a successful full installer download. The app's restart confirmation was driven through the UI. Logs recordquitAndInstalland the actual NSIS installer launch. The app relaunched, and installed executable metadata and the uninstall registry changed from0.1.1-local.21273to0.1.2. Build and updater logs, installer hashes and executable metadata are kept locally and available on request.Unsigned build, localhost feed. The app asks to install update 0.1.2 and restart.
Unsigned build, localhost feed. The app relaunched after installation. This screen has no version label; the executable and registry receipts below establish 0.1.2.
Unsigned build, localhost feed. Rendering of saved before/after JSON receipts, not a terminal capture. FileVersion changes to 0.1.2, both executable SHA-256 values are shown, the registry reports 0.1.2, and Authenticode remains NotSigned.
This is unsigned build and local update evidence only. Both installers report
NotSigned. The supported unsigned build'sapp-update.ymlhas nopublisherName; pinned electron-updater 6.8.9 returns before calling its Windows signature verifier in that configuration. This run therefore did not exercise PowerShell signature verification, timeout or retry. The signed build's four Azure Trusted Signing settings were absent at preflight, so production signed signature-retry verification remains blocked on an authorized signing configuration and suitable signed test setup. No signing identity was generated, validation setting disabled or candidate source changed.Not checked:
nullagain, so upgrades need this revisited.Credits
Thanks to the reporter of #20345 for the diagnosis, repeat-run timing and suggested retry option.
Production fix and tests written with Claude Opus 5.5 via claude_auto using the Claude Code harness; PR description and images by GPT-6.1 Sol using the Codex harness, both in T3 Code.
🤖 Generated with Claude Code