Repository navigation
Description
What happened
Every in-app update on my Windows work laptop fails with the installer dialog "Failed to uninstall old application files. Please try running the installer again.: -1073740940" and leaves %LOCALAPPDATA%\Programs\t3code empty. Every stable update since 0.1.5 has done this. The previous version survives only in %TEMP%\ns*.tmp\old-install.
Diagnosis
-1073740940 is 0xC0000374 (heap corruption). The cause is in the StdUtils 1.14 plugin that electron-builder 26.16.1 bundles, and it runs in every T3 installer and uninstaller:
- electron-builder generates
${isUpdated}and the other flags asStdUtils.TestParameter(app-builder-libout/targets/nsis/nsisScriptGenerator.js:29-33,NsisTarget.js:592). The installer also callsStdUtils.GetParameter(templates/nsis/include/installer.nsh:17). - Both go through StdUtils
init_mainargs, which takes msvcrt's argv from__wgetmainargsand registersfree_mainargsfor DLL_PROCESS_DETACH (ParameterParser.cpp:92-97,StdUtils.cpp:60). free_mainargscallsfree()on eachargv[i], then onargv(ParameterParser.cpp:67-78). msvcrt returns argv as one block with the strings inside it, so these free pointers it does not own. With heap validation on, the process is killed at exit.- The old uninstaller has already moved the install into its
$PLUGINSDIR\old-install(uninstaller.nsh:164-187) when it dies.installUtil.nsh:215retries 5 times, thenhandleUninstallResult(installUtil.nsh:108-129) shows the dialog and quits. Nothing is installed.
Confirmed by experiment with NSIS 3.0.4.1 and nsis-resources-3.4.1, what T3 builds with (build-desktop-artifact.ts:2905 sets no toolsets.nsis):
- A one-section installer calling
StdUtils.GetParameter, or the generated${isUpdated}macro: 0xC0000374 on every run and command line. Same with the NSIS 3.12 bundle, which ships the same StdUtils. - Empty installer, System, nsExec, UAC, WinShell, getProcessInfo, and StdUtils GetAllParameters, TrimStr, GetLibVersion: exit 0.
- msvcrt via P/Invoke, 32 and 64 bit: every
argv[i]lies inside theargvallocation.
Why only some machines: unknown. Freeing an interior pointer is undefined, and whether it is fatal depends on heap state and policy. Here system Heap TerminateOnError is ON, and an endpoint agent injects a DLL into every process. The repro under Steps will show whether a clean machine is affected.
Suggested fix 1, needed regardless because uninstallers already on users' machines have the bug. In apps/desktop/resources/installer.nsh:
!macro customUnInstallCheck
${ifNot} ${Errors}
${andIf} $R0 != 0
${andIf} ${FileExists} "$installationDir\${APP_EXECUTABLE_FILENAME}"
MessageBox MB_OK|MB_ICONEXCLAMATION "$(uninstallFailed): $R0" /SD IDOK
SetErrorLevel 2
Quit
${endIf}
!macroendTested on NSIS 3.0.4.1 against a child exiting -1073740940: with the old exe gone the install continues; with it present the installer quits with level 2, as today.
Suggested fix 2, root cause: stop using StdUtils TestParameter and GetParameter in the existing app-builder-lib patch (GetAllParameters is safe), or bundle a StdUtils without those frees. A plain FileFunc ${GetOptions} swap is not a drop-in: it prefix-matches (--updated-not), and my exact-match version failed on the real call (--updated _?=<dir>).
Steps to reproduce
- Windows 11 24H2 x64 with Heap TerminateOnError ON (
Get-ProcessMitigation -System), per-user T3 Code (Beta). - Accept an in-app update.
- About 50 s later the dialog appears and the install folder is empty.
Minimal repro without T3 (NSIS 3.0.4.1, electron-builder's plugins and includes):
Unicode true
SilentInstall silent
RequestExecutionLevel user
!include StdUtils.nsh
OutFile probe.exe
Section
${StdUtils.GetParameter} $0 "x" ""
SectionEndprobe.exe exits 0xC0000374 every time here, 0 without the GetParameter line.
Version
0.1.5 through 0.1.9 (Beta). The code paths are unchanged on main (e9e934b).
Environment
Windows 11 Enterprise 24H2 x64 (10.0.26100.9711, msvcrt 7.0.26100.9711), per-user install, managed corporate device, 570 GB free
Evidence
Event 1000, 2026-11-10, five times in 51 s, then the same for T3-Code-0.1.8-x64.exe:
Faulting application: old-uninstaller.exe 0.1.7.0, path %TEMP%\nsdBA44.tmp\old-uninstaller.exe
Faulting module: ntdll.dll 10.0.26100.9711, exception 0xc0000374, offset 0x000fd71f
WER also archived old-uninstaller.exe crashes for the 11/02 and 11/04 updates. 0.1.9 /S install on 11/12: complete install, then exit -1073740940.
Probe exit codes (NSIS 3.0.4.1, 3 runs each):
empty installer 0x00000000
StdUtils.GetParameter 0xC0000374
StdUtils.TestParameter (isUpdated) 0xC0000374
StdUtils.GetAllParameters 0x00000000
System / nsExec / UAC / WinShell 0x00000000Related issues
#25450 is the same dialog with code 2 (a leftover process, fixed by #25831). #27486 covers partial or empty installs, and its empty-folder case had low disk space. electron-builder#8664 has the same -1073740940 for other apps, closed without a cause. Not reported to electron-builder or StdUtils yet.
Fix applied or workaround
Close T3 completely. Delete %LOCALAPPDATA%\Programs\t3code and the T3 Code key under HKCU\Software\Microsoft\Windows\CurrentVersion\Uninstall, run the downloaded installer with /S, ignore its exit code, and check the installed exe version. With no old uninstaller to run, the install completes. An emptied install can be restored from %TEMP%\ns*.tmp\old-install.
Note from the reporter: Big fan, Theo. I've been watching for years and I think your tools are amazing. Thanks for building T3 Code. Mike Morel
Filed by
Claude Code (Claude Opus 5.5, claude-opus-5-5), following .github/triage/PLAYBOOK.md
Activity