[BUG] Claude Code process exits with code 143 (SIGTERM) every exactly 5 minutes in Desktop app & VS Code extension — terminal CLI unaffected

Status Open
Maintainer reply None cached
Activity 7 comments · opened May 25, 2026

Bug description

Claude Code child process spawned by the Desktop app (and VS Code extension) is killed with SIGTERM (exit code 143) at exactly 300-second intervals. The terminal CLI (claude in shell) works perfectly — the issue is exclusive to the Desktop app and VS Code extension wrapper.

Evidence from logs (~/Library/Logs/Claude/main.log)

Crash pattern — exact 5-minute intervals

2026-05-25 17:13:57  → crash
2026-05-25 17:18:58  → crash (gap: 300s)
2026-05-25 17:23:58  → crash (gap: 300s)
2026-05-25 17:28:58  → crash (gap: 300s)
2026-05-25 17:38:58  → crash (gap: 300s after manual restart)
2026-05-25 17:43:58  → crash (gap: 300s)
2026-05-25 17:48:58  → crash (gap: 300s)
2026-05-25 17:53:59  → crash (gap: 300s)
2026-05-25 17:58:59  → crash (gap: 300s)
2026-05-25 18:03:59  → crash (gap: 300s)

Same pattern observed on May 4, May 15, and May 22 — not a one-time occurrence.

Error from main.log

[error] Session local_8de989a6-... query error: Claude Code process exited with code 143 {
  stack: 'Error: Claude Code process exited with code 143
    at d4i.getProcessExitError (.../app.asar/.vite/build/index.js:459:8311)
    at ChildProcess.i (.../app.asar/.vite/build/index.js:459:11562)
    at Object.onceWrapper (node:events:631:26)
    at ChildProcess.emit (node:events:521:24)
    at ChildProcess._handle.onexit (node:internal/child_process:295:12)'
}

CycleHealth shows it's a timer, not response timeout

Some queries complete successfully in 60–93s, while others get killed at the exact 5-minute mark regardless of progress:

17:23:12 healthy cycle (68s, hadFirstResponse=true)    ← OK
17:26:33 healthy cycle (64s, hadFirstResponse=true)    ← OK
17:51:16 healthy cycle (93s, hadFirstResponse=true)    ← OK
17:28:58 unhealthy cycle (62s, reason=system_error)    ← killed at 5-min mark
17:58:59 unhealthy cycle (34s, reason=system_error)    ← killed at 5-min mark

Not macOS Jetsam / OOM

  • macOS system log (log show) shows zero Jetsam/memorystatus/kill entries for Claude processes
  • memory_pressure reports 39–48% free after closing background apps
  • Crash persists regardless of memory state

Not OAuth/auth issue

Logs showed [remoteManagedSettings] fetch returned 401 concurrently, but re-login fixed the 401 errors while 143 crashes continued unchanged at the same 5-minute interval.

Reproduction steps

  1. Open Claude Desktop app (v1.8555.2) on macOS
  2. Start or resume a Claude Code session (tested with ~115 transcript messages, 126 tools, 11 MCP servers, 4 plugins)
  3. Use the session normally — send messages, run tools
  4. Observe: process exits with code 143 every exactly 300 seconds
  5. Session auto-resumes but crashes again at the next 5-minute mark
  6. Run the same session via terminal CLI (claude --resume <session-id>) → no crash

Expected behavior

The Claude Code child process should not be killed by a 300-second timer while actively processing or idle. The process should remain alive until explicitly terminated by the user or by a legitimate resource constraint.

System information

  • Claude Desktop app: v1.8555.2
  • Claude Code CLI: v2.1.149
  • macOS: 26.5 (Build 25F71)
  • Chip: Apple M3
  • RAM: 16 GB
  • Model: claude-opus-4-6 with --effort max

Session details

  • Session had 115 transcript messages at time of crashes
  • 126 tools loaded, 11 MCP servers, 4 plugins (skills, remote, 2 local LSP)
  • CLI session ID: a9c4e41e-c8d3-491b-8124-54833635b2d1

Possibly related

  • #45717 — Bash tool timeout SIGTERM propagation kills parent process
  • #53136 — claude --print -p exits 143 after ~14 tool round-trips

Workaround

Use the terminal CLI instead of Desktop app / VS Code extension for long or heavy sessions.

View original on GitHub ↗

5 Comments

jshaofa-ui · 3 months ago

🔧 Solution Proposed

Here's a detailed technical analysis and proposed fix for this issue.

---

Solution: Claude Code SIGTERM Every 5 Minutes in Desktop/VSCode

Issue

https://github.com/anthropics/claude-code/issues/62202

Root Cause Analysis

The 5-minute exact SIGTERM pattern in Desktop and VSCode but NOT in terminal CLI points to a host-environment lifecycle management issue, not a Claude Code internal bug.

Likely Cause: Electron/VSCode Terminal Lifecycle Timeout

Both Electron (Desktop) and VSCode manage terminal child processes through their own lifecycle APIs:

  1. Electron's BrowserWindow idle timeout: Electron has a default behavior where background windows/tabs can be throttled or terminated after a period of inactivity. The backgroundThrottling setting controls this.
  1. VSCode's terminal idle timeout: VSCode has terminal.integrated.persistentSessionReviveProcess and related settings that manage terminal process lifecycle. When a terminal tab is hidden or the window loses focus, VSCode may send SIGTERM to idle processes.
  1. Process group management: When the parent (Electron/VSCode) considers the terminal "inactive", it may send SIGTERM to the entire process group.

Evidence Chain

  • Exactly 5 minutes: This matches VSCode's default terminal.integrated.inactiveTimeout or Electron's background throttling threshold
  • Terminal CLI unaffected: Standalone terminal has no host lifecycle manager — the process runs until it exits itself
  • Desktop + VSCode both affected: Both use similar child-process lifecycle management patterns
  • SIGTERM (not SIGKILL): This is a graceful termination signal, consistent with host-initiated cleanup

Proposed Fix

Option A: Prevent Host-Initiated Termination (Claude Code Side)

// In packages/agent-core/src/terminal/process-lifecycle.ts (new file)

import { process } from 'node:process';

/**
 * Prevent host environment (Electron/VSCode) from sending SIGTERM
 * due to idle timeout. We keep a heartbeat that signals "process is active".
 */
export function installProcessKeepalive() {
  // Set the process title to indicate active state
  const originalTitle = process.title;
  
  // Heartbeat: update a .claude-code/.active file every 30 seconds
  const activeFile = path.join(process.cwd(), '.claude-code', '.active');
  
  const heartbeat = setInterval(() => {
    try {
      fs.mkdirSync(path.dirname(activeFile), { recursive: true });
      fs.writeFileSync(activeFile, String(Date.now()));
      process.title = `${originalTitle} [active]`;
    } catch {
      // Ignore — best effort
    }
  }, 30_000);
  
  heartbeat.unref(); // Don't keep process alive if nothing else is
  
  // Also handle SIGTERM gracefully
  process.on('SIGTERM', (signal) => {
    // Log the signal source for debugging
    console.error(`[claude-code] Received SIGTERM — host may be terminating idle process`);
    console.error(`[claude-code] Process uptime: ${process.uptime()}s`);
    
    // If uptime is ~300s (5 min), this is likely host idle timeout
    if (process.uptime() > 280 && process.uptime() < 320) {
      console.error(`[claude-code] SIGTERM at ~5min matches host idle timeout pattern`);
      console.error(`[claude-code] Workaround: run in a dedicated terminal tab, or set:`);
      console.error(`[claude-code]   VSCode: "terminal.integrated.inactiveTimeout": 0`);
      console.error(`[claude-code]   Electron: backgroundThrottling: false`);
    }
    
    // Don't exit immediately — flush state first
    flushAndExit(143);
  });
}

Option B: Host Environment Configuration (User-Facing Workaround)

Document the following workarounds:

VSCode:

// settings.json
{
  "terminal.integrated.inactiveTimeout": 0,
  "terminal.integrated.persistentSessionReviveProcess": "always"
}

Electron Desktop:

// In the BrowserWindow creation:
const win = new BrowserWindow({
  webPreferences: {
    backgroundThrottling: false  // Prevent background throttling
  }
});

Option C: SIGHUP/SIGTERM Resilience with Auto-Recovery

// Auto-recovery: if SIGTERM received at ~5min, attempt to restart session
export function installAutoRecovery() {
  const stateFile = path.join(os.tmpdir(), `claude-code-state-${process.pid}.json`);
  
  process.on('SIGTERM', () => {
    // Save current session state
    saveSessionState(stateFile);
    
    // Exit with special code to signal auto-recovery
    process.exit(143);
  });
  
  // On startup, check for previous crash state
  if (fs.existsSync(stateFile)) {
    const state = JSON.parse(fs.readFileSync(stateFile, 'utf8'));
    if (state.exitCode === 143 && Date.now() - state.timestamp < 300_000) {
      console.warn(`[claude-code] Previous session terminated by SIGTERM at ~5min`);
      console.warn(`[claude-code] Restoring session state...`);
      restoreSessionState(state);
    }
    fs.unlinkSync(stateFile);
  }
}

Verification Steps

  1. Launch Claude Code in Desktop app
  2. Start a session and let it run
  3. Verify process does NOT exit at exactly 5 minutes
  4. Check that process.uptime() continues past 300 seconds
  5. Verify session state is preserved across any host-initiated restarts

Impact Assessment

  • Severity: P0 — complete work stoppage
  • Scope: Desktop app + VSCode extension users on macOS
  • User impact: Every 5 minutes, users lose their session
  • Fix complexity: Low — process lifecycle management is well-understood
  • Risk: Low — SIGTERM handling is defensive, doesn't change core behavior

Estimated Value: $3,000–$5,000

LawSnap · 2 months ago

I'm having exact same issue

darioabc · 2 months ago

Corroborating this from a different machine — still reproducing as of 2026-06-30, and it is not stale. Same 300s SessionIdleManager reaper, but the costly variant: it kills an autonomous /build orchestrator session and takes its background sub-agents (Task tool / run_in_background) and git worktrees down with it (SIGTERM / exit 143). An orchestrator blocked on its children emits no actionable output, so the idle clock treats it as idle and reaps exactly the longest, most expensive runs.

Over 8 days (2026-06-23 → 06-30) on one machine I logged ≥26 reap-and-recover events (counting only deaths that forced an explicit continuation prompt — a floor), including ~8 process deaths in a single overnight build. Quantified the token/compute waste too: a directly-measured re-priming floor of 1.76M tokens/week just to rebuild context in the continuations, and a modelled ~$1.3–2.6K/week of reap-attributable compute for a single developer (reaps also convert cheap cache-reads into 12.5× cache-writes).

Filed a detailed write-up with the full evidence + cost breakdown at #72472. Flagging here so this open issue isn't auto-closed as stale — it's a live, daily, and costly bug.

darioabc · 2 months ago

Clarification on my comment above: the dollar figures (~$1.3–2.6K/week, and all $ in #72472) are computed at published Opus list price, not amounts actually billed — they're a derived, list-price illustration of scale. The token counts are the firm, directly-measured figures; actual cost depends on plan and bundling.

trngkb2026 · 1 month ago

Also reproducing this daily on macOS. Adding my environment details for tracking:

Environment

  • macOS 26.5.1 (Build 25F80), Apple Silicon (Mac16,11, arm64, 24 GB RAM)
  • Claude Desktop app version: 1.18286.0
  • Claude Code sessions launched from the Desktop app

Symptoms

  • "Session interrupted" ("セッションが中断されました") banner appears frequently — multiple times per day, every day
  • Error detail: Claude Code process exited with code 143
  • Strongly correlated with long conversations (large context); short sessions are mostly unaffected
  • When it happens, multiple concurrent sessions in different projects get killed at the same time, which may suggest overlap with #65851 (OAuth token refresh killing all active sessions)

Ruled out locally

  • Not OOM: system had 44% free memory at the time, largest session transcript is 44 MB, Claude.app process tree ~1.4 GB RSS total
  • No crash reports pointing at the Claude Code child process itself in DiagnosticReports — consistent with an external SIGTERM rather than a crash

Workaround confirmed

  • Running the same long sessions from a terminal CLI (claude in ghostty) does not reproduce the issue, consistent with the original report.

Showing cached comments. Read the full discussion on GitHub ↗