openclaw - 💡(How to fix) Fix `openclaw message send` hangs indefinitely on Windows; leaks zombie node processes; no caller-timeout recovery

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…

openclaw message send <channel> <chat-id> <text> invoked from a Windows shell or subprocess.run never exits. The spawned node.exe child keeps running and accumulates as a zombie even after the parent fires its own timeout. Multiple invocations (e.g. from a cron-driven notifier) pile up zombie processes that consume CPU and RAM.

Root Cause

Actual

  • Command never returns.
  • Underlying node.exe child remains running indefinitely.
  • Subsequent invocations stack — observed >5 leaked node children after a few cron iterations.
  • The actual Telegram message may have been delivered or may not have been; the caller cannot tell from the CLI's exit (because there is no exit) whether anything reached the channel.

Fix Action

Workaround

Bypass the CLI entirely and call the provider API directly. We did this for a cron-driven notifier (congresswatch): replaced openclaw message send with stdlib urllib against the Telegram Bot API. Reliable and fast (~200 ms).

Code Example

# Gateway running, bot configured, chat id valid
openclaw message send telegram <chat-id> "test"
# Process never returns. Ctrl+C in pwsh exits the shell wrapper but
# the underlying node.exe child remains in Task Manager.

---

import subprocess
try:
    subprocess.run(
        ["openclaw", "message", "send", "telegram", "<chat-id>", "test"],
        timeout=30, check=True,
    )
except subprocess.TimeoutExpired:
    pass
# Caller hits TimeoutExpired but the spawned node child is still alive
# and continues running indefinitely.
RAW_BUFFERClick to expand / collapse

Summary

openclaw message send <channel> <chat-id> <text> invoked from a Windows shell or subprocess.run never exits. The spawned node.exe child keeps running and accumulates as a zombie even after the parent fires its own timeout. Multiple invocations (e.g. from a cron-driven notifier) pile up zombie processes that consume CPU and RAM.

Environment

  • OpenClaw: 2026.5.6 (also seen on 2026.4.25)
  • OS: Windows 10/11 x64
  • Node: v24.15.0
  • Shell: PowerShell 7 (pwsh) and cmd.exe
  • Caller: Python subprocess.run(..., timeout=30) and direct shell invocation
  • Channel: telegram (Telegram Bot plugin) — bot is responsive; gateway is healthy at the time of the call

Repro

# Gateway running, bot configured, chat id valid
openclaw message send telegram <chat-id> "test"
# Process never returns. Ctrl+C in pwsh exits the shell wrapper but
# the underlying node.exe child remains in Task Manager.
import subprocess
try:
    subprocess.run(
        ["openclaw", "message", "send", "telegram", "<chat-id>", "test"],
        timeout=30, check=True,
    )
except subprocess.TimeoutExpired:
    pass
# Caller hits TimeoutExpired but the spawned node child is still alive
# and continues running indefinitely.

Expected

Command sends the message, prints success, exits cleanly. On caller-side timeout, the child process is terminated.

Actual

  • Command never returns.
  • Underlying node.exe child remains running indefinitely.
  • Subsequent invocations stack — observed >5 leaked node children after a few cron iterations.
  • The actual Telegram message may have been delivered or may not have been; the caller cannot tell from the CLI's exit (because there is no exit) whether anything reached the channel.

Workaround

Bypass the CLI entirely and call the provider API directly. We did this for a cron-driven notifier (congresswatch): replaced openclaw message send with stdlib urllib against the Telegram Bot API. Reliable and fast (~200 ms).

Suspected cause

The CLI appears to wait on a gateway WebSocket confirmation that never closes (or never arrives) before exiting. The cmd-shim wrapping that npm uses on Windows also doesn't propagate signals cleanly to the node child, so caller timeouts can't kill the child.

Impact

Production cron-driven notifiers cannot trust the CLI for delivery. Silent CLI hangs look identical to silent successes from a cron's perspective unless the operator explicitly checks for zombie processes or queries the provider's API to verify delivery.

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…

Still need to ship something?

×6

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

Back to top recommendations

TRENDING

openclaw - 💡(How to fix) Fix `openclaw message send` hangs indefinitely on Windows; leaks zombie node processes; no caller-timeout recovery