[BUG] Regression in 2.1.280: Remote Control sessions killed by mid-session SIGSEGV at 0x0 in JSC idle-time GC (Bun 1.4.3, decoded stack, VS Code Remote-SSH / Linux)

Status Open
Reported on v2.1.280
Maintainer reply None cached
Activity 6 comments · opened Sep 24, 2026

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

The bundled Bun runtime SIGSEGVs at address 0x0 on the main thread, mid-session, roughly 34 minutes into a healthy session. Startup is reliable; this is not the glibc-2.44 startup cluster.

This is a regression. Remote Control sessions on this machine ran reliably until 2.1.280; the crashes began with it and continue on 2.1.281. Last known good is 2.1.279 or earlier.

The decoded crash report puts the fault in the JSC garbage collector's beginMarking, invoked from Bun's before-idle GC hook — i.e. the event loop was about to go to sleep, Bun opportunistically ran a collection in the mutator thread, and JSC null-dereferenced starting the mark phase.

JSC::MarkedSpace::beginMarking                      MarkedSpace.cpp:423
beginMarking                                        Heap.cpp:955
JSC::Heap::runBeginPhase                            Heap.cpp:2121
JSC::Heap::runCurrentPhase                          Heap.cpp:2020
JSC::Heap::collectInMutatorThread                   Heap.cpp:2678
Bun__JSC_onBeforeWait                               BunJSCEventLoop.cpp:96
us_loop_run_bun_tick                                epoll_kqueue.c:508
auto_tick_active                                    VirtualMachine.rs:3363
<bun_runtime::cli::run_command::Run>::start         run_command.rs:1517
main                                                mod.rs:209

Crash report: https://bun.report/1.4.3/l_1f08e57bmgggkQuhogCkt1hsE6+9trE435trE2vnwrEmov/pCg050/B6k8m7Bo+s1gCy+i0gC2790iCA2AA

In practice this is what kills Remote Control sessions. This SIGSEGV is the error surfaced in the VS Code window each time a Remote Control session dies. At the time of writing, ListAgents in a surviving session shows two peer Remote Control sessions as offline that were not deliberately ended.

Environment

| | |
|---|---|
| Claude Code | 2.1.281, VS Code extension's bundled binary (~/.vscode-server/extensions/anthropic.claude-code-2.1.281-linux-x64/resources/native-binary/claude) |
| Bundled Bun | 1.4.3 (f08e57bec) |
| Entrypoint | VS Code extension over Remote-SSH (macOS client → Debian host; the binary runs on the Debian host) |
| OS | Debian GNU/Linux 13 (trixie) |
| Kernel | 6.12.57+deb13-amd64 x86_64 |
| glibc | 2.41-12 |
| CPU | Intel i9-9900K — sse42 popcnt avx avx2, no avx512 |
| RAM | 50 GB total, ~28 GB free |
| Remote Control | enabled for the session |

Process args at crash: --output-format stream-json --verbose --input-format stream-json --max-thinking-tokens 31999

Resource state at crash: Elapsed: 2026732ms (~33 m 47 s) · RSS 0.25GB · Peak 0.32GB · Commit 0.51GB · Faults: 0 — so this is not memory exhaustion.

Possibly relevant: the heartbeat interval doubles just before the fault

The last stderr lines are CCRClient: Heartbeat sent. Their spacing degrades sharply about four minutes before the crash:

| Heartbeat (UTC) | Δ from previous |
|---|---|
| 23:56:16.498 | — |
| 23:56:36.178 | 19.7 s |
| 23:56:57.258 | 21.1 s |
| 23:57:16.884 | 19.6 s |
| 23:57:35.938 | 19.1 s |
| 23:58:33.651 | 57.7 s |
| 23:59:37.674 | 64.0 s |
| 00:00:38.498 | 60.8 s |
| (crash) | |

A steady ~20 s cadence becomes ~60 s for the final three beats. Whether the loop was stalling before the fault or the heartbeat simply backs off when idle, I can't tell from outside — but given the faulting frame is the before-idle GC hook, the correlation between "loop increasingly idle" and "crash in the idle-GC path" seems worth recording.

Why I believe this is distinct from the existing reports

  • #95655 (mid-session SIGSEGV, linux-x64, Bun 1.4.3) is the nearest relative by symptom, and that binary is stripped — so this report supplies a decoded stack for that shape of crash. But the version histories do not line up: that reporter sees crashes from 2.1.210 through 2.1.278, whereas this machine was completely stable until 2.1.280. Same subsystem, possibly not the same defect. Different environment too (Mageia 10, glibc 2.42, kernel 6.18, Konsole CLI, no Remote Control). Happy for these to be merged if triage concludes they're one bug.
  • #91914 is also Linux JSC-GC, but the fault is on the HeapHelper thread inside IsoCellSet::parallelNotEmptyMarkedBlockSource during parallel marking. This one is the mutator/main thread in MarkedSpace::beginMarking, i.e. the start of a collection, not parallel drain.
  • #92045 is the GC mark phase on a dedicated GC thread at 0xFFFFFFFFFFFFFFFF (Windows, Bun 1.4.1). Different thread, different frame, different address.
  • #86657 is claude-vscode after a long session, but Windows, v2.1.229, Bun 1.4.0, and no decoded stack.
  • #96498 is a VS Code + Remote Control crash, but Windows and specific to the branch-switch dialog on resume.

Searched: SIGSEGV, segfault, panic main thread, Bun 1.4.3, CCRClient, Remote Control crash, bun.report, 2.1.281.

What Should Happen?

The session should not die. An idle-time GC should not be able to null-dereference and take the process down — and when the runtime does abort, the Remote Control session should surface something better than a raw Bun panic in the VS Code window, and ideally be recoverable rather than left offline with no path back.

Reproduction

No deterministic repro. It happens on long-running sessions with Remote Control enabled; the crash lands while the session is idle or between operations rather than under load. The strongest signal available is the version boundary: the same machine, same workflow and same Remote-SSH setup were stable before 2.1.280, so whatever landed in 2.1.280 is the place to look. Happy to run any instrumented build, enable core dumps, or collect BUN_ debug env output on request.

Error Messages/Logs

[DEBUG] CCRClient: Heartbeat sent 2026-09-23T23:56:16.498Z
[DEBUG] CCRClient: Heartbeat sent 2026-09-23T23:56:36.178Z
[DEBUG] CCRClient: Heartbeat sent 2026-09-23T23:56:57.258Z
[DEBUG] CCRClient: Heartbeat sent 2026-09-23T23:57:16.884Z
[DEBUG] CCRClient: Heartbeat sent 2026-09-23T23:57:35.938Z
[DEBUG] CCRClient: Heartbeat sent 2026-09-23T23:58:33.651Z
[DEBUG] CCRClient: Heartbeat sent 2026-09-23T23:59:37.674Z
[DEBUG] CCRClient: Heartbeat sent 2026-09-24T00:00:38.498Z
============================================================
Bun v1.4.3 (f08e57bec) Linux x64
Linux Kernel v6.12.57 | glibc v2.41
CPU: sse42 popcnt avx avx2
Args: "/home/jason/.vscode-server/extensions/anthropic.claude-code-2.1.281-linux-x64/resources/native-binary/claude" "--output-format" "stream-json" "--verbose" "--input-format" "stream-json" "--max-thinking-tokens" "31999" "--"...
Features: Bun.stderr(2) Bun.stdin(2) Bun.stdout(2) abort_signal(92) fetch(108) jsc spawn(10) standalone_executable yaml_parse(11) claude_code
Builtins: "bun:main" "node:assert" "node:async_hooks" "node:buffer" "node:child_process" "node:constants" "node:crypto" "node:dns" "node:dns/promises" "node:events" "node:fs" "node:fs/promises" "node:http" "node:http2" "node:https" "node:module" "node:net" "node:os" "node:path" "node:path/posix" "node:path/win32" "node:perf_hooks" "node:process" "node:readline" "node:stream" "node:stream/consumers" "node:stream/promises" "node:string_decoder" "node:timers/promises" "node:tls" "node:tty" "node:url" "node:util" "node:util/types" "node:zlib" "ws"
Elapsed: 2026732ms | User: 9094ms | Sys: 2127ms
RSS: 0.25GB | Peak: 0.32GB | Commit: 0.51GB | Faults: 0
Machine: 54.75 GB

panic(main thread): Segmentation fault at address 0x0
oh no: Bun has crashed. This indicates a bug in Bun, not your code.

And the VS Code surface:

Error: Claude Code process terminated by signal SIGSEGV.

View original on GitHub ↗

5 Comments

asyncjason · 20 days ago

Additional occurrence from the same machine, found in the extension's own log
(~/.vscode-server/data/logs/<session>/exthost2/Anthropic.claude-code/Claude VSCode.log).
Two crashes, 23 minutes apart, identical signature — both panic(main thread): Segmentation
fault at address 0x0
, both Bun 1.4.3 / extension 2.1.281.

| | crash A | crash B (the one in the report) |
|---|---|---|
| Time (UTC) | 2026-09-23 23:37:10 | 2026-09-24 00:00:41 |
| Session length at fault | 7371295 ms (~2 h 3 m) | 2026732 ms (~34 m) |
| RSS | 0.33 GB | 0.25 GB |
| Peak | 0.74 GB | 0.32 GB |
| Commit | 6.40 GB | 0.51 GB |
| Faults | 0 | 0 |

Worth noting:

  • Session length is not the variable. Two hours and thirty-four minutes both end the same way,

so this is not a slow leak reaching a threshold. Neither run was near memory pressure either —
RSS peaks under 0.75 GB on a 54.75 GB machine, Faults: 0 both times.

  • The two runs differ ~12× in committed memory (6.40 GB vs 0.51 GB) and still fault at the same

place, which argues against heap size being the trigger.

  • Both faults are at 0x0, not a wild address. Combined with the decoded frame

(MarkedSpace::beginMarking reached via Bun__JSC_onBeforeWait → collectInMutatorThread),
this looks more like a null/uninitialised structure at the start of a collection than heap
corruption discovered during one.

Frequency in practice: these are the two captured in one log file; the user's experience is that
Remote Control sessions do not survive, consistently, since 2.1.280. Prior to 2.1.280 the same
machine and workflow were stable.

asyncjason · 20 days ago

Correcting and sharpening the reproduction picture, from the reporter's direct experience plus
process state on the host.

It is not session age. The two crashes were at 2 h 3 m and 34 m. Meanwhile one session on the
same host has now been up 16 h 51 m through both of them and is still running. Duration is not
the variable.

It hits new and resumed sessions alike, non-deterministically. It has killed a freshly created
session (no --resume) and it has killed resumed ones; some older sessions survived and others did
not. There is no clean "new crashes / old survives" split.

Several sessions run concurrently on this host. Right now:

pid 1874312  up 16:51:13  session 285103d3   <- survivor, through both crashes
pid 1900108  up 24:36     session 0507e4b3
pid 1902827  up 00:55     <new, no --resume>
pid 1902959  up 00:00     <new, no --resume>

All are spawned by the VS Code extension with identical arguments apart from --resume:

--output-format stream-json --verbose --input-format stream-json --max-thinking-tokens 31999
--permission-prompt-tool stdio --setting-sources=user,project,local --permission-mode auto
--allow-dangerously-skip-permissions --debug --debug-to-stderr --enable-auth-status --no-chrome
--replay-user-messages

So nothing at the argument level distinguishes a session that dies from one that lives, and the
reporter's practical experience is that opening further sessions tends to kill them while this one
keeps going. Whether concurrency is causal or coincidental I can't establish from here, but with
four processes sharing a host and a fault inside the idle-time GC path, it seemed worth recording
rather than leaving out.

Two things checked and not found, to save anyone else looking: no Epoch mismatch /
session_not_active anywhere in the extension log (so this is not #89183), and no memory pressure
in either crash (Faults: 0, peak RSS 0.74 GB on a 54.75 GB machine).

asyncjason · 20 days ago

Correction to my previous comment. I wrote that "opening further sessions tends to kill them while
this one keeps going" — that overstates it. The reporter has since opened a new session and it
started and ran fine.

The accurate statement is that this is intermittent. New sessions sometimes crash and sometimes
do not; resumed sessions likewise; one long-lived session has survived throughout. There is no
reliable trigger we can point at, and no deterministic reproduction.

What still holds, and is measured rather than inferred:

  • Two crashes on this host with an identical signature — `panic(main thread): Segmentation fault at

address 0x0, decoded to MarkedSpace::beginMarking via Bun__JSC_onBeforeWait →
collectInMutatorThread`.

  • Session age is not the variable (2 h 3 m, 34 m, versus a 16 h+ survivor).
  • Not memory pressure (Faults: 0; peak RSS 0.74 GB on a 54.75 GB machine).
  • Not #89183 (no Epoch mismatch / session_not_active in the extension log).
  • The version boundary is the one strong signal: stable before 2.1.280, crashing since.

Apologies for the noise — better to have that on the record than leave a claim in the thread that
the next data point disproved.

asyncjason · 20 days ago

Update: the crashes stopped, with no local change. Recording it because the timing may be a
lead only Anthropic can follow.

  • Both crashes fall in a 23-minute window: 2026-09-23 23:37:10 UTC and 2026-09-24 00:00:41 UTC.
  • ~16 hours since, across multiple new and resumed sessions, with none.
  • The bundled binary is byte-identical throughout — same mtime (2026-09-23 13:23:29 -0700) and

same sha256 before and after. Nothing was updated, reinstalled or reconfigured on this host in
between, and the extension is still 2.1.281.

So whatever stopped it was not a client change. Either the bug is bursty and has gone quiet on its
own, or something server-side in that window was a contributing factor. I can't distinguish those
from here, but if anything shipped or rolled back on the service around 2026-09-24 00:00 UTC,
that would be worth correlating against — a GC crash in the mutator thread is local code, but the
allocation and event pattern that provokes it is driven by what the client is being sent.

Methodology note, in case anyone greps this log themselves: counting occurrences of
panic(main thread) in the extension log overcounts. That log also records webview messages,
so crash text pasted into a conversation shows up as an additional hit. Only the blocks preceded by
a From claude: line and accompanied by the Bun v1.4.3 ... Elapsed: ... RSS: banner are real
faults. By that test there are exactly two here, not the five a naive grep reports.

asyncjason · 20 days ago

Latest testing (2026-09-24 16:23 UTC)

Still no recurrence. Deliberately opened new sessions to try to provoke it; all started and ran
normally. Five concurrent sessions on the host right now:

pid 1874312  up 16:56:21  session 285103d3   <- ran through both crashes, still alive
pid 1900108  up 29:45     session 0507e4b3
pid 1902827  up 06:03     <new>
pid 1903182  up 03:01     <new>
pid 1903510  up 00:00     <new>

16 h 22 m since the last crash, with the binary unchanged throughout. Confirmed crash count is
still exactly two — verified by requiring the From claude: prefix and the Bun v1.4.3 … Elapsed …
RSS
banner, so the pasted-text false positives are excluded.

So: new sessions are not reliably affected, concurrency does not reliably provoke it, and session
age is not the variable. This is intermittent and currently dormant.

Hypothesis (speculation, flagged as such — not an observation)

Everything above is measured. This part is not, and I'd rather label it than have it read as a
finding.

A fault inside MarkedSpace::beginMarking may be a symptom rather than the defect. The
collector is the first thing to walk the whole heap, so it is where earlier damage tends to surface
— the crash site and the bug site are often different. A null at 0x0 beginning the mark phase is
consistent with a space/block structure that was never initialised or was cleared by something
else, rather than with a bug in marking itself.

If that is what is happening, a payload-driven trigger would fit the evidence well:

  • an unusual or malformed payload routes through a native path (a binding, a decoder, an oversized

or unexpected field);

  • that path damages heap metadata, and nothing faults at the time;
  • the next collection walks the heap and dies — which is why the fault lands in the idle-time GC

hook rather than under load;

  • and if the payload shape stopped being sent, the crashes would stop with no client change —

which is exactly what was observed, with a byte-identical binary.

This would also explain why the two crashes cluster inside 23 minutes and then vanish for 16 hours.

I cannot evidence any of that from outside the runtime, and it may be wrong. Recording it only
because it suggests looking beyond GC code — at what ran before the collection — and because the
service side can correlate the 23:37–00:01 UTC window against what was being sent to clients then.

Showing cached comments. Read the full discussion on GitHub ↗