Repository navigation
Gate the managed-local provenance probe so it cannot start wsl.exe during Windows session teardown #1572
Description
What
During a Windows session-end sequence the tray can still create a wsl.exe child process. At that point process creation fails with STATUS_DLL_INIT_FAILED (0xc0000142) and Windows shows an Application Error dialog; the same failure is recorded in the System log as Application Popup, Event ID 26.
This issue covers one production file: the process-start boundary of the managed-local gateway port-provenance probe.
Split out of #1571. #1571 keeps the full evidence trail (the 16-day Event 26 burst census, tray log excerpts, the five mid-session bursts, the family split against the unrelated XLGuard.sys popup). Read #1571 for evidence; this issue is the narrow job.
Where
src/OpenClaw.Connection/ManagedLocalGatewayPortProvenanceService.cs
IsExpectedWslGatewayListeningis declared on the interface at:32and implemented at:97.- The probe is started at
:102:using var process = Process.Start(probe.StartInfo); - The
ProcessStartInfois built byCreateExpectedWslGatewayProbeat:120–:124. - There is a second start in the same file at
:213(process = Process.Start(psi);, psi built at:202). - Callers inside the same file:
:334,:361,:389,:419. - Neither start consults any Windows session-ending signal. Searches across
src/,tests/anddocs/find noSessionEnding,WM_ENDSESSION,WM_QUERYENDSESSION,SM_SHUTTINGDOWNorHasShutdownStartedimplementation.
Scope — deliberately one file
- Change only the process-start boundary in
ManagedLocalGatewayPortProvenanceService.cs. - Do not touch
docs/, settings or configuration, schema, or any other project. - Do not change the reconnect loop (
src/OpenClaw.Shared/WebSocketClientBase.cs) or the keep-alive path (src/OpenClaw.Tray.WinUI/App.xaml.cs); those are tracked as separate follow-up issues. - Do not refactor
AppShutdownCoordinatoror the existing ordered-shutdown design recorded indocs/ARCHITECTURE.md. - Do not add a new user-facing setting.
A previous single issue covering all three spawn paths produced an autonomous fix artifact that spanned three subsystems and was rejected upstream as too broad for autonomous execution. Keeping this to one file is the point of the split.
Required behaviour
- Once the process has observed that the Windows session is ending,
IsExpectedWslGatewayListeningmust return without creating a process — noProcess.Start, so nowsl.exe, so no0xc0000142and no Event 26. - The same applies to the second start at
:213. - Behaviour when no session end is in progress must be unchanged, including the existing "no Windows listener remains, check WSL" path.
- The session-ending signal must be an injected abstraction (an interface or delegate the probe consults), not a direct static call, so a unit test can force "session ending" without shutting Windows down.
- Wiring a concrete Windows session-end source (
WM_QUERYENDSESSION/WM_ENDSESSIONon the tray window, orSystemEvents.SessionEnding) is out of scope here and belongs to a follow-up. This issue only needs the seam plus a safe default. - Do not use
Environment.HasShutdownStartedas the whole answer; on its own it is not reliable evidence that a Windows session-end sequence is in progress.
- Wiring a concrete Windows session-end source (
- The refusal must be observable in the log at the point of refusal (one line is enough), so a future report can be diagnosed from the tray log alone.
Acceptance
./build.ps1
dotnet test ./tests/OpenClaw.Connection.Tests/OpenClaw.Connection.Tests.csproj --no-restore
Required regression test
In tests/OpenClaw.Connection.Tests, a test that:
- substitutes a session-ending signal that reports "ending",
- calls
IsExpectedWslGatewayListening, - asserts that no process was started.
Assert on the injected seam (the process-runner / start-info factory), not on a real wsl.exe — the test must pass on a machine with no WSL and must not launch anything.
What I can and cannot contribute
- I can confirm the reported behaviour on Windows 11 Home China build
10.0.26300with OpenClaw Companion2026.9.4.0, and I can supply Event 26 / Event 1074 timelines and tray-log excerpts on request. - I do not have a working build environment for this repository, so I cannot run
./build.ps1or the test projects. Someone else needs to verify.
Metadata
Metadata
Assignees
Labels
Type
Fields
Priority
Projects
- StatusShow more project fieldsBacklog
Activity
clawsweeper commentedon Oct 1, 2026
Codex review: this still needs some work. Reviewed October 1, 2026, 9:02 AM ET / 13:02 UTC.
Summary
The process-start guard remains absent on current main and in v2026.9.4. This narrowly scoped prerequisite is still useful; no open PR was found owning the shutdown guard.
Likely related people: bkudiess and shanselman are medium-confidence routing candidates from merged connection work.
Reproducibility: yes. for the source-level admission gap: reachable reconnect authorization invokes a platform that starts processes without observing session teardown. The Windows 0xc0000142 race was reported with event timelines but was not independently reproduced.
Root-cause cluster
Relationship:
partial_overlapCanonical: #1571
Summary: The parent retains the evidence for session-teardown launches; this issue owns one deliberately separated process-start boundary.
Members:
canonical: Tray spawnswsl.exeduring session teardown, producing an "Application Error 0xc0000142" popup on every shutdown/restart #1571 - Open evidence umbrella explicitly delegates this narrower production boundary.partial_overlap: Tray keep-alive can still start during Windows session end and its repair adapter ignores the cancellation token #1573 - Tracks keepalive admission and cancellation, sharing the planned lifecycle signal but requiring separate caller changes.partial_overlap: Reconnect retry loop invokes reconnect authorization with no Windows session-ending check #1574 - Tracks stopping reconnect authorization before it reaches this probe.adjacent_distinct: fix(connection): a cached wslrelay proof allows a token after the listener changes #1510 - Repairs listener-identity revalidation during credential proof rather than session-teardown launch admission.Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything.
Next step
A focused launch-admission repair has clear source boundaries and deterministic validation; establish failing regression coverage before implementing the seam.
Review details
Best possible solution:
Gate both launch boundaries through injected lifecycle state, preserve failed-proof semantics, and connect the shared production signal in a separate focused follow-up.
Do we have a high-confidence way to reproduce the issue?
Yes for the source-level admission gap: reachable reconnect authorization invokes a platform that starts processes without observing session teardown. The Windows 0xc0000142 race was reported with event timelines but was not independently reproduced.
Is this the best way to solve the issue?
Yes as a staged boundary repair: injected lifecycle and process-start seams allow deterministic zero-launch regression coverage within the requested scope. Real shutdown protection still needs the separately deferred production signal.
AGENTS.md: found and applied where relevant.
Remaining risk / open question:
Codex review notes: model internal, reasoning medium; reviewed against f4122a8927e7.
Label changes
Label changes:
P2: The reported shutdown dialogs are alarming but do not prevent the gateway from working after reboot.impact:ux-friction: Background process launches can produce confusing Windows application-error dialogs during ordinary shutdown.issue-rating: 🦞 diamond lobster: Current issue advisory state selects this label.clawsweeper:source-repro: Current issue advisory state selects this label.clawsweeper:queueable-fix: Current issue advisory state selects this label.clawsweeper:fix-shape-clear: Current issue advisory state selects this label.Label justifications:
P2: The reported shutdown dialogs are alarming but do not prevent the gateway from working after reboot.impact:ux-friction: Background process launches can produce confusing Windows application-error dialogs during ordinary shutdown.Evidence reviewed
Acceptance criteria:
What I checked:
src/OpenClaw.Connection/ManagedLocalGatewayPortProvenanceService.cs:102, f4122a8927e7)src/OpenClaw.Connection/GatewayConnectionManager.cs:719, f4122a8927e7)docs/CONNECTION_ARCHITECTURE.md:628, f4122a8927e7)tests/OpenClaw.Connection.Tests/ManagedLocalGatewayPortProvenanceServiceTests.cs:95, f4122a8927e7)src/OpenClaw.Connection/ManagedLocalGatewayPortProvenanceService.cs:102, 3c43751b2bac)wsl.exeduring session teardown, producing an "Application Error 0xc0000142" popup on every shutdown/restart #1571 (comment). The later split comment retains the parent as evidence and assigns separate production boundaries to the three child issues: Tray spawnswsl.exeduring session teardown, producing an "Application Error 0xc0000142" popup on every shutdown/restart #1571 (comment). This issue expressly defers concrete Windows session-source wiring.Likely related people:
How this review workflow works
@clawsweeper re-reviewcomments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.@clawsweeper re-reviewor@clawsweeper re-runon an open PR or issue to request a fresh review only.@clawsweeper reviewto request a fresh review only.@clawsweeper autofix,@clawsweeper automerge,@clawsweeper fix ci, or@clawsweeper address review.@clawsweeper explainto ask for more context, or@clawsweeper stopto stop active automation.petruslin commentedon Oct 1, 2026
There is now a shared session-ending contract to code against
Filed as reporter: #1575 —
Provide one shared Windows session-ending signal and wire it for production use.This issue's text asks for an injected session-ending abstraction and then explicitly puts the concrete Windows source out of scope, deferring it to a follow-up. #1575 is that follow-up. It owns the contract, the Windows implementation, and the production wiring; it deliberately does not touch any of the three consumer call sites (
#1572,#1573,#1574).So the shape of this one is unchanged but its dependency is now concrete:
src/OpenClaw.Connection/ManagedLocalGatewayPortProvenanceService.cs.Process.Startis the point that actually creates the process. Both starts, and every in-file caller that can reach them, should decline once the session-end transition has been observed.#1575 also asks for the transition and not only a latched state, which matters here: declining as early as possible is preferable, and a latched flag that only becomes visible after teardown has begun may be read too late.
Nothing here requires a maintainer decision, so this one can proceed as soon as #1575 lands.