claude-code - 💡(How to fix) Fix [BUG] Desktop-only: CLI exit 143 / system_error on cycles past ~5 min — bare CLI works fine with same binary, same model, same context

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…

Error Message

[error] Session local_<id> query error: Claude Code process exited with code 143 { stack: 'Error: Claude Code process exited with code 143 at ...getProcessExitError (app.asar/.vite/build/index.js:406:8122) at ChildProcess.i (app.asar/.vite/build/index.js:406:11166) at ChildProcess.emit (node:events:521:24) at ChildProcess.handle.onexit (node:internal/child_process:295:12)' } [info] [CCD CycleHealth] unhealthy cycle for local<id> (<duration>s, hadFirstResponse=true, reason=system_error)

Root Cause

This points at Desktop's CycleHealth watchdog, its stream-json IPC handling, or partial-message processing as the likely source. The fact that the CLI process exits (not hangs, not signals) suggests Desktop sends it a SIGTERM (143 = 128 + 15) when CycleHealth flips unhealthy, and CycleHealth flips because something in Desktop's wrapper has a ~5-minute threshold that the bare CLI never has to deal with.

Code Example

[error] Session local_<id> query error: Claude Code process exited with code 143 {
  stack: 'Error: Claude Code process exited with code 143
      at ...getProcessExitError (app.asar/.vite/build/index.js:406:8122)
      at ChildProcess.i (app.asar/.vite/build/index.js:406:11166)
      at ChildProcess.emit (node:events:521:24)
      at ChildProcess._handle.onexit (node:internal/child_process:295:12)'
}
[info] [CCD CycleHealth] unhealthy cycle for local_<id> (<duration>s, hadFirstResponse=true, reason=system_error)

---

Healthy   (n=19): 15, 25, 28, 31, 33, 33, 34, 35, 39, 42, 45, 46, 47, 53, 61, 62, 71, 204, 307
Unhealthy (n=10): 21, 49, 128, 174, 256, 305, 314, 333, 333, 336

---

--output-format stream-json --input-format stream-json --verbose
--include-partial-messages --replay-user-messages
--effort <level> --model claude-opus-4-7[1m]
--permission-prompt-tool stdio --allow-dangerously-skip-permissions
--resume <session-id> --allowedTools ... --plugin-dir ...
RAW_BUFFERClick to expand / collapse

Preflight Checklist

  • I have searched existing issues and this hasn't been reported (closest related: #51164 ECONNRESET on large-context, #44362 Opus 4.6 1M CLI hang — both manifest differently)
  • This is a single bug report
  • I am using the latest version of Claude Code

What's Wrong?

Claude Code running inside Claude Desktop Local Agent Mode reliably crashes with Claude Code process exited with code 143 after the cycle hits ~5 minutes of wall-clock duration. Claude Desktop logs the cycle as [CCD CycleHealth] unhealthy cycle ... reason=system_error and surfaces the generic "The session ended unexpectedly. Please try again." message.

Critical contrast: the standalone claude CLI run directly in a terminal does NOT have this problem. I keep multiple long-lived claude CLI sessions open in terminal tabs for days at a time (3–7+ days of continuous uptime, on the same machine, same network, same model, same context size) with no exit-143 crashes. The Anthropic SDK happily streams 5+ minute responses to the bare CLI. The bug appears only when the CLI is spawned by Claude Desktop with its structured I/O wrapper.

This is not a hang — the CLI process exits cleanly (no crash report in ~/Library/Logs/DiagnosticReports/, no signal), it just terminates without producing a final result message on its stream-json output. Per the Desktop source in app.asar, system_error is the catch-all when the SDK's output stream ends without a result message and there is no explicit api_error to surface. The preceding telemetry event is lam_stream_ended_diagnostic.

The pattern is sharply bimodal in cycle duration: cycles that complete in well under 5 minutes are healthy, cycles that approach 5 minutes are almost certainly killed — in Desktop only.

What Should Happen?

A long-running turn should be able to run past 5 minutes in Desktop just like it does in the bare CLI. Whatever Desktop is layering on top of the spawned CLI — watchdog, IPC pipe handling, stream-json parser, partial-message handling — should not produce a different failure mode from the same binary running directly.

At minimum: if Desktop's wrapper does decide the cycle is unhealthy, the CLI should be sent a real cancellation that lets it emit a result-message with an api_error subtype so Desktop's CycleHealth shows the actual cause instead of the generic "session ended unexpectedly."

Error Messages/Logs

Sequence in ~/Library/Logs/Claude/main.log for every Desktop occurrence:

[error] Session local_<id> query error: Claude Code process exited with code 143 {
  stack: 'Error: Claude Code process exited with code 143
      at ...getProcessExitError (app.asar/.vite/build/index.js:406:8122)
      at ChildProcess.i (app.asar/.vite/build/index.js:406:11166)
      at ChildProcess.emit (node:events:521:24)
      at ChildProcess._handle.onexit (node:internal/child_process:295:12)'
}
[info] [CCD CycleHealth] unhealthy cycle for local_<id> (<duration>s, hadFirstResponse=true, reason=system_error)

No DiagnosticReport for the claude binary is generated (no segfault / no jetsam).

Cycle-duration distribution from a single afternoon/evening (29 cycles observed in Desktop):

Healthy   (n=19): 15, 25, 28, 31, 33, 33, 34, 35, 39, 42, 45, 46, 47, 53, 61, 62, 71, 204, 307
Unhealthy (n=10): 21, 49, 128, 174, 256, 305, 314, 333, 333, 336

Half the unhealthy cycles (5/10) cluster in a tight 31-second window at 305–336 seconds — i.e. immediately past the 5-minute mark. The 17 healthy cycles all completed in under 75 seconds; the two healthy outliers (204s, 307s) suggest cycles that approach the threshold but happen to land before it.

For contrast, in the same time window I had four bare-CLI sessions running in terminal tabs (process uptimes of 3, 4, 4, and 7+ days). Same machine, same network, same Anthropic SDK binary, same model, comparably-sized contexts, many cycles longer than 5 minutes each. Zero exit-143 events. The bug is in Desktop's wrapper, not the CLI itself or the API.

Why the client doesn't appear to be the source

  • The CLI binary contains DEFAULT_TIMEOUT = 600000 (10 min) for the Anthropic SDK request timeout. The CLI's only 300000-ms (5 min) constant in scope is the Node HTTP server requestTimeout default — not the API client.
  • The bare CLI happily completes >5-minute turns. So whatever 5-minute kill is happening, it isn't the CLI's own SDK timeout.
  • The CLI does not appear to retry on this path — there is no api_error event in the log, no retryAttempt records (unlike #51164 which goes through 10 retries on ECONNRESET).

This points at Desktop's CycleHealth watchdog, its stream-json IPC handling, or partial-message processing as the likely source. The fact that the CLI process exits (not hangs, not signals) suggests Desktop sends it a SIGTERM (143 = 128 + 15) when CycleHealth flips unhealthy, and CycleHealth flips because something in Desktop's wrapper has a ~5-minute threshold that the bare CLI never has to deal with.

Steps to Reproduce

  1. Open Claude Desktop, start a Local Agent Mode session on claude-opus-4-7[1m] with effort=xhigh.
  2. Issue prompts that require many tool calls per turn (file reads, bash, sub-agents, etc.) so individual cycles run several minutes.
  3. Observe that cycles which approach 5 minutes consistently fail with the log signature above.
  4. Contrast: run the same claude binary from ~/Library/Application Support/Claude/claude-code/<ver>/claude.app/Contents/MacOS/claude directly in a terminal with comparable model/effort, do the same kind of long-turn work. It will not crash.

Desktop-spawn flags (for reference)

Desktop spawns the CLI with structured I/O:

--output-format stream-json --input-format stream-json --verbose
--include-partial-messages --replay-user-messages
--effort <level> --model claude-opus-4-7[1m]
--permission-prompt-tool stdio --allow-dangerously-skip-permissions
--resume <session-id> --allowedTools ... --plugin-dir ...

The bare-CLI invocation uses the interactive TTY default (no --output-format flags). The contrast strongly implicates the structured-I/O / partial-message path.

Claude Model

Opus (specifically claude-opus-4-7[1m] — the 1M context beta variant). Effort: xhigh.

Environment

  • Claude Code (bundled in Desktop): 2.1.142
  • Claude Desktop: 1.7196.1
  • macOS: 26.3 on arm64 (Apple Silicon)

Is this a regression?

Unknown. Earliest occurrence I have in main.log is 2026-05-09.

Related Issues

  • #51164 — large-context ECONNRESET with retries (different surface: clean api_error retries, not silent exit)
  • #44362 — Opus 4.6 1M CLI hang on macOS (different surface: hang, not exit; reported on bare CLI not Desktop)
  • #46987, #49500 — "Stream idle timeout - partial response received" (similar root cause; both currently marked duplicate)

What's distinct about this report: Desktop-only, silent exit (143) rather than hang or api_error, and reproducible contrast with the same binary working fine in a terminal.

Suggested investigation

  1. What 5-minute threshold exists in Desktop's local-agent-mode wrapper that does not exist in the bare CLI? CycleHealth interval, IPC pipe high-water mark, HTTP/2 idle timer, partial-message ack timeout — something in that wrapper has a 300s ceiling.
  2. When that threshold trips, the CLI process should not just be killed and the cycle marked system_error. Either (a) it shouldn't trip at all (Desktop should match the bare-CLI behavior), or (b) Desktop should let the CLI emit a result-message with subtype: api_error so the user gets a useful error instead of "session ended unexpectedly."
  3. Worth checking if --include-partial-messages or --replay-user-messages (Desktop-specific flags) have a code path that the bare CLI doesn't exercise.

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

claude-code - 💡(How to fix) Fix [BUG] Desktop-only: CLI exit 143 / system_error on cycles past ~5 min — bare CLI works fine with same binary, same model, same context