Skip to content

[Mac App] node.invoke system.run causes WebSocket disconnection on macOS #89423

Description

@Lvan185

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:

  1. 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.
  2. 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.
  3. 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

  1. Stopped the CLI node (openclaw-node daemon) to eliminate dual-node conflicts
  2. Removed ~/Library/LaunchAgents/ai.openclaw.node.plist to prevent auto-restart of CLI
  3. Removed the CLI node's pairing from the server
  4. Confirmed only the Mac App (client: openclaw-macos/node) is connected
  5. Confirmed the Mac App has all required macOS permissions
  6. Verified that node.describe, location_get, notify work reliably (these use different RPC methods)

How to Reproduce

  1. Pair an OpenClaw Mac App (v2026.5.28) on a Mac (M1, macOS 26.5.0) with a server
  2. 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"
    
  3. 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:

  1. Mac App internal logs~/Library/Application Support/OpenClaw/ contains bridge.sock, canvas/, identity/, model-catalog/ but no logs directory
  2. Console.app logs — filter for OpenClaw process messages on the Mac
  3. macOS log show --process OpenClaw output
  4. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Normal backlog priority with limited blast radius.clawsweeper:needs-live-reproClawSweeper needs live local, crabbox, or manual validation to confirm this issue.clawsweeper:needs-maintainer-reviewClawSweeper marked this issue as needing maintainer review before automation.clawsweeper:no-new-fix-prClawSweeper does not recommend queueing a new automated fix PR for this issue.impact:otherThis issue has meaningful maintainer-visible impact outside the owned taxonomy.issue-rating: 🐚 platinum hermitGood issue quality with a plausible reproduction path needing some confirmation.staleMarked as stale due to inactivity

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions