openclaw - ✅(Solved) Fix [Bug]: [Windows] openclaw update hangs after "✓ Updating via package manager" completes [1 pull requests, 1 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#78445Fetched 2026-05-07 03:36:52
View on GitHub
Comments
1
Participants
2
Timeline
11
Reactions
2
Author
Timeline (top)
mentioned ×3subscribed ×3labeled ×2commented ×1

On Windows PowerShell, running openclaw update from version 2026.5.3-1 to newer version, the console output hangs after showing successful package manager update. The update completes successfully (65 seconds) but the console does not return to the prompt.

Root Cause

On Windows PowerShell, running openclaw update from version 2026.5.3-1 to newer version, the console output hangs after showing successful package manager update. The update completes successfully (65 seconds) but the console does not return to the prompt.

Fix Action

Fixed

PR fix notes

PR #78483: fix(update): pipe post-core child stdio on Windows to prevent terminal hang (#78445)

Description (problem / solution / changelog)

Summary

  • Problem: After openclaw update completes on Windows, the PowerShell/CMD prompt never returns. The upgrade itself succeeds (running openclaw --version in a new window shows the new version), but the original terminal is permanently blocked.
  • Why it matters: Every Windows user who runs openclaw update must kill their PowerShell/CMD window and open a new one after every update, making the update experience broken on Windows.
  • What changed: continuePostCoreUpdateInFreshProcess now spawns the post-core-update child with stdio:"pipe" on Windows instead of stdio:"inherit". A new exported helper resolvePostCoreUpdateChildStdio encapsulates the platform selection. When piped, the child's stdout/stderr streams are relayed to the parent process so terminal output is still displayed.
  • What did NOT change: Behavior on Linux/macOS is unchanged (stdio:"inherit" still used). stopPostCoreUpdateChild / taskkill logic is unchanged. All non-Windows update paths are identical.

Change Type (select all)

  • Bug fix

Scope (select all touched areas)

  • UI / DX

Linked Issue/PR

  • Closes #78445
  • This PR fixes a bug or regression

Real behavior proof (required for external PRs)

  • Behavior or issue addressed: Terminal hang after openclaw update completes on Windows.
  • Real environment tested: Unit tests on macOS (Linux/Darwin); Windows behavior validated by logic (the bug is OS console-handle inheritance — confirmed by reading the Node.js child_process and Windows console handle documentation).
  • Exact steps or command run after this patch: pnpm test src/cli/update-cli/update-command.test.ts --reporter=verbose
  • Evidence after fix (terminal output):
 RUN  v4.1.5 /Users/dev/openclaw

 ✓ |cli| src/cli/update-cli/update-command.test.ts > resolveGatewayInstallEntrypointCandidates > prefers index.js before legacy entry.js 1ms
 ✓ |cli| src/cli/update-cli/update-command.test.ts > resolveGatewayInstallEntrypoint > prefers dist/index.js over dist/entry.js when both exist 1ms
 ✓ |cli| src/cli/update-cli/update-command.test.ts > resolveGatewayInstallEntrypoint > falls back to dist/entry.js when index.js is missing 0ms
 ✓ |cli| src/cli/update-cli/update-command.test.ts > shouldPrepareUpdatedInstallRestart > prepares package update restarts when the service is installed but stopped 0ms
 ✓ |cli| src/cli/update-cli/update-command.test.ts > shouldPrepareUpdatedInstallRestart > does not install a new service for package updates when no service exists 0ms
 ✓ |cli| src/cli/update-cli/update-command.test.ts > shouldPrepareUpdatedInstallRestart > keeps non-package updates tied to the loaded service state 0ms
 ✓ |cli| src/cli/update-cli/update-command.test.ts > resolveUpdatedGatewayRestartPort > uses the managed service port ahead of the caller environment 0ms
 ✓ |cli| src/cli/update-cli/update-command.test.ts > resolveUpdatedGatewayRestartPort > falls back to the post-update config when no service port is available 0ms
 ✓ |cli| src/cli/update-cli/update-command.test.ts > resolvePostInstallDoctorEnv > uses the managed service profile paths for post-install doctor 0ms
 ✓ |cli| src/cli/update-cli/update-command.test.ts > resolvePostInstallDoctorEnv > keeps the caller env when no managed service env is available 0ms
 ✓ |cli| src/cli/update-cli/update-command.test.ts > shouldUseLegacyProcessRestartAfterUpdate > never restarts package updates through the pre-update process 0ms
 ✓ |cli| src/cli/update-cli/update-command.test.ts > shouldUseLegacyProcessRestartAfterUpdate > keeps the in-process restart path for non-package updates 0ms
 ✓ |cli| src/cli/update-cli/update-command.test.ts > resolvePostCoreUpdateChildStdio > returns "pipe" on Windows so the child never inherits the parent console handles 0ms
 ✓ |cli| src/cli/update-cli/update-command.test.ts > resolvePostCoreUpdateChildStdio > returns "inherit" on non-Windows platforms 0ms

 Test Files  1 passed (1)
      Tests  14 passed (14)
  • Observed result after fix: New test resolvePostCoreUpdateChildStdio > returns "pipe" on Windows passes; macOS/Linux regression test passes; all existing tests green.
  • What was not tested: Live openclaw update run on a real Windows PowerShell session — the bug is in the Windows console-handle inheritance model which is not reproducible in this macOS dev environment. The logic is mechanically correct per Node.js docs.

Root Cause (if applicable)

  • Root cause: continuePostCoreUpdateInFreshProcess called spawn(node, argv, { stdio: "inherit" }). On Windows, stdio:"inherit" passes the calling process's STDIN, STDOUT, and STDERR handles (which are Windows console HANDLE objects) directly to the child via handle inheritance. The Windows Console subsystem keeps the console "attached" to any process that holds an open handle. PowerShell/CMD waits for the console to be fully released before returning the prompt. The child spawns its own sub-processes (doctor, gateway-restart wrapper, etc.) which also inherit those handles transitively. When the child exits, the grandchildren may still hold the handles, causing the hang.
  • Missing detection / guardrail: No Windows-specific stdio configuration existed in the spawn call.
  • Contributing context: The same stdio:"inherit" works correctly on macOS/Linux because Unix shells track process exit via wait(), not console handle reference counting.

Regression Test Plan (if applicable)

New tests for resolvePostCoreUpdateChildStdio (the extracted helper):

  1. "returns 'pipe' on Windows so the child never inherits the parent console handles" — passes "win32" as platform, asserts result is "pipe".
  2. "returns 'inherit' on non-Windows platforms" — passes "linux" and "darwin", asserts result is "inherit" in both cases.

Environment

  • OS: macOS (Darwin 25.x) / target fix: Windows PowerShell
  • Runtime/container: Node.js 22, local dev
  • Model/provider: N/A (infrastructure fix)
  • Integration/channel (if any): N/A
  • Relevant config (redacted): N/A

Steps (to reproduce before fix on Windows)

  1. Open PowerShell
  2. Run openclaw update
  3. Wait for "✓ Updating via package manager" success message
  4. Terminal never returns prompt (blocked indefinitely)

Expected (after fix)

  • Terminal returns to prompt immediately after update completes, just like on macOS/Linux.

Actual (after fix)

  • Child process runs with stdio:"pipe"; output is relayed via child.stdout.pipe(process.stdout) and child.stderr.pipe(process.stderr); no console handles are inherited; terminal returns when the child process exits.

Evidence

  • Failing test/log before + passing after (terminal output above)

Human Verification (required)

  • Verified scenarios: resolvePostCoreUpdateChildStdio("win32") returns "pipe"; resolvePostCoreUpdateChildStdio("linux") / "darwin" returns "inherit"; existing test suite still passes.
  • Edge cases checked: child.stdout / child.stderr are only piped when childStdio === "pipe" (optional chaining guards against them being null when stdio is not piped).
  • What you did not verify: Live Windows PowerShell test — requires a Windows machine with openclaw installed.

Review Conversations

  • I replied to or resolved every bot review conversation I addressed in this PR.
  • I left unresolved only the conversations that still need reviewer or maintainer judgment.

Compatibility / Migration

  • Backward compatible? Yes — behavior change is Windows-only; all other platforms unchanged
  • Config/env changes? No
  • Migration needed? No

Risks and Mitigations

  • Risk: Piping child output on Windows may not preserve terminal formatting (ANSI codes, progress bars) as faithfully as stdio:"inherit".
    • Mitigation: The post-core-update child runs a secondary openclaw update pass that primarily installs plugins and prints progress text — it does not use interactive TTY features. Any loss of color/formatting is a minor cosmetic trade-off for a working terminal prompt.

Changed files

  • CHANGELOG.md (modified, +1/-0)
  • src/cli/update-cli/update-command.test.ts (modified, +15/-0)
  • src/cli/update-cli/update-command.ts (modified, +23/-1)
RAW_BUFFERClick to expand / collapse

Bug type

Regression (worked before, now fails)

Beta release blocker

No

Summary

On Windows PowerShell, running openclaw update from version 2026.5.3-1 to newer version, the console output hangs after showing successful package manager update. The update completes successfully (65 seconds) but the console does not return to the prompt.

Steps to reproduce

Bug Description On Windows PowerShell, running openclaw update from version 2026.5.3-1 to newer version, the console output hangs after showing successful package manager update. The update completes successfully but the console does not return to the prompt.

Steps to Reproduce

  1. Run openclaw update on Windows PowerShell
  2. Wait for the update to complete

Actual Behavior Console shows: Updating OpenClaw... | o ✓ Updating via package manager (65.32s)

and then freezes. The process is actually complete (verified by running openclaw --version shows new version), but the prompt never returns.

Expected behavior

Should continue executing health checks and plugin checks after package manager update completes, until the entire update process finishes and returns to the prompt.

Actual behavior

no prompt no active next step

OpenClaw version

2026.5.5

Operating system

windows 11

Install method

openclaw update

Model

minimax

Provider / routing chain

openclaw minimax

Additional provider/model setup details

The update command hangs after npm completes. The process is actually alive (verified by running openclaw --version shows new version after force-terminating the hung process), suggesting the issue is with console output flushing or the subsequent health check phase on Windows PowerShell.

Logs, screenshots, and evidence

Impact and severity

No response

Additional information

No response

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

FAQ

Expected behavior

Should continue executing health checks and plugin checks after package manager update completes, until the entire update process finishes and returns to the prompt.

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING