Bug Report: Mac App (openclaw-macos) node.invoke WebSocket disconnects during system.run
Environment
| Field |
Value |
| Gateway (Server) |
OpenClaw 2026.5.28 (e932160) |
| Mac App |
openclaw-macos v2026.5.28 (UI version) |
| Mac Hardware |
MacBookAir10,1 (Apple M1) |
| macOS Version |
26.5.0 (Sequoia) |
| Server OS |
Ubuntu Linux 5.4.119-19-0009.56 (x64) |
| Connection |
Tailscale Direct (private network via Tailscale) |
| Node Type |
client: openclaw-macos/node · device: Mac · hw: MacBookAir10,1 |
| Permissions (Mac App) |
accessibility=yes, appleScript=yes, camera=yes, location=yes, microphone=yes, notifications=yes, screenRecording=yes, speechRecognition=yes |
Symptom
The Mac App node frequently disconnects its WebSocket connection when executing any node.invoke command with system.run that takes longer than ~200ms. Shorter commands (<200ms) occasionally succeed.
What works reliably:
nodes list, nodes status (server-side, no node.invoke needed)
node.describe (read-only metadata queries)
location_get ✅
notify ✅
camera_snap ✅
- Minimal node shell commands (e.g.,
echo done, trivial ls on small directories)
What causes disconnects (~80-90% failure rate):
exec via node with any medium-duration command
system.run commands that take >200ms
log show on macOS (requires ~0.5-1 second)
find ~/Library on macOS
sleep 0.1 through openclaw nodes shell
Error Logs (Server Side)
Typical error sequence (from gateway logs):
{"level":"info","subsystem":"gateway/ws"} ⇄ res ✗ node.invoke 275ms errorCode=UNAVAILABLE errorMessage=Error: node disconnected (system.run) conn=bcd674de…9a8f id=83212baa…b3f4
{"level":"error"} [tools] exec failed: Error: node disconnected (system.run) raw_params={"host":"node","node":"<redacted>","timeout":30}
{"level":"error"} [tools] exec failed: Error: node disconnected (system.run) raw_params={"host":"node","node":"<redacted>","timeout":15}
Timeline of one burst (within ~30 seconds):
| Time (CST) |
Command |
Duration |
Result |
| 19:19:37 |
find ~/Library |
275ms |
❌ node disconnected |
| 19:19:40 |
find ~/Library (with details) |
734ms |
❌ node disconnected |
| 19:19:42 |
echo "collecting" |
202ms |
✅ OK |
| 19:19:53 |
log show (background) |
89ms |
❌ node disconnected |
| 19:19:59 |
log show (full query) |
829ms |
❌ node disconnected |
Observations:
- The Mac App PID does not change across disconnects (PID remained 727 throughout)
- No crash reports found in
~/Library/Logs/DiagnosticReports/
- Disconnection happens on the WebSocket layer (errorCode=UNAVAILABLE)
- The Mac App auto-reconnects within seconds, confirming the App process stays alive
- Only
system.run triggers the issue — other node capabilities (location, notify, camera) work fine
Root Cause Hypothesis
The most likely cause is that macOS AppKit's system.run implementation blocks the main thread (or the WebSocket event loop) while executing shell commands, causing the WebSocket heartbeat to time out.
Possible mechanisms:
- Main thread blocking: If the Mac App uses
Process.run() (synchronous) instead of Process() with async I/O on a background queue, the main thread freezes during command execution.
- AppKit run loop starvation: If
NSTask.waitUntilExit is called on the main thread, the WebSocket's run loop source doesn't get a chance to send pings/handle keepalives.
- macOS power management: On M1 MacBooks, macOS aggressively throttles background app processes. However, this is less likely since the disconnection is deterministic (only on
system.run) and the App stays alive.
What We've Already Done to Isolate
- Stopped the CLI node (
openclaw-node daemon) to eliminate dual-node conflicts
- Removed
~/Library/LaunchAgents/ai.openclaw.node.plist to prevent auto-restart of CLI
- Removed the CLI node's pairing from the server
- Confirmed only the Mac App (client: openclaw-macos/node) is connected
- Confirmed the Mac App has all required macOS permissions
- Verified that
node.describe, location_get, notify work reliably (these use different RPC methods)
How to Reproduce
- Pair an OpenClaw Mac App (v2026.5.28) on a Mac (M1, macOS 26.5.0) with a server
- From the server, run any command through the Mac App node that executes for >200ms:
openclaw nodes shell "<mac-node-name>" --command "sleep 0.3 && echo ok"
- The node disconnects during execution, and the error
node disconnected (system.run) appears in server logs
What We Could Not Collect (Mac-side Logs)
Due to the disconnection, we could not remotely collect:
- Mac App internal logs —
~/Library/Application Support/OpenClaw/ contains bridge.sock, canvas/, identity/, model-catalog/ but no logs directory
- Console.app logs — filter for
OpenClaw process messages on the Mac
- macOS
log show --process OpenClaw output
- Activity Monitor — CPU/memory/energy impact during
system.run
If the bug reporter could provide these or a link to gather Mac-side diagnostics, that would help pinpoint the exact cause.
Summary
This is a regression or architectural issue in the OpenClaw macOS App where system.run (shell command execution) frequently causes WebSocket disconnections. The App itself does not crash — only the RPC connection is lost. The root cause is likely a main-thread/event-loop blocking issue in the macOS process management implementation. A fix would involve ensuring shell command execution happens asynchronously on a background thread without blocking the WebSocket heartbeat.
Bug Report: Mac App (openclaw-macos) node.invoke WebSocket disconnects during system.run
Environment
Symptom
The Mac App node frequently disconnects its WebSocket connection when executing any
node.invokecommand withsystem.runthat takes longer than ~200ms. Shorter commands (<200ms) occasionally succeed.What works reliably:
nodes list,nodes status(server-side, no node.invoke needed)node.describe(read-only metadata queries)location_get✅notify✅camera_snap✅echo done, triviallson small directories)What causes disconnects (~80-90% failure rate):
execvia node with any medium-duration commandsystem.runcommands that take >200mslog showon macOS (requires ~0.5-1 second)find ~/Libraryon macOSsleep 0.1throughopenclaw nodes shellError Logs (Server Side)
Typical error sequence (from gateway logs):
Timeline of one burst (within ~30 seconds):
find ~/Libraryfind ~/Library(with details)echo "collecting"log show(background)log show(full query)Observations:
~/Library/Logs/DiagnosticReports/system.runtriggers the issue — other node capabilities (location, notify, camera) work fineRoot Cause Hypothesis
The most likely cause is that macOS AppKit's
system.runimplementation blocks the main thread (or the WebSocket event loop) while executing shell commands, causing the WebSocket heartbeat to time out.Possible mechanisms:
Process.run()(synchronous) instead ofProcess()with async I/O on a background queue, the main thread freezes during command execution.NSTask.waitUntilExitis called on the main thread, the WebSocket's run loop source doesn't get a chance to send pings/handle keepalives.system.run) and the App stays alive.What We've Already Done to Isolate
openclaw-nodedaemon) to eliminate dual-node conflicts~/Library/LaunchAgents/ai.openclaw.node.plistto prevent auto-restart of CLInode.describe,location_get,notifywork reliably (these use different RPC methods)How to Reproduce
node disconnected (system.run)appears in server logsWhat We Could Not Collect (Mac-side Logs)
Due to the disconnection, we could not remotely collect:
~/Library/Application Support/OpenClaw/containsbridge.sock,canvas/,identity/,model-catalog/but no logs directoryOpenClawprocess messages on the Maclog show --process OpenClawoutputsystem.runIf the bug reporter could provide these or a link to gather Mac-side diagnostics, that would help pinpoint the exact cause.
Summary
This is a regression or architectural issue in the OpenClaw macOS App where
system.run(shell command execution) frequently causes WebSocket disconnections. The App itself does not crash — only the RPC connection is lost. The root cause is likely a main-thread/event-loop blocking issue in the macOS process management implementation. A fix would involve ensuring shell command execution happens asynchronously on a background thread without blocking the WebSocket heartbeat.