Repository navigation
[Bug][macOS] Bundled Bun 1.3.14 exits with SIGTRAP after connection reset and TLS verification failures #1419
Description
Client or integration
Codex App
Area
Service lifecycle
Summary
OpenCodex 2.11.1 went offline twice without an ocx stop command. In both cases, the bundled Bun process terminated with a native EXC_BREAKPOINT / SIGTRAP on its main thread shortly after a connection reset followed by TLS certificate verification failures.
After the second crash, the page opened by ocx gui also became unreachable because the dashboard was served by the same terminated process.
Expected behavior: a transient upstream connection/TLS failure should fail or retry the affected request while the proxy stays alive, or at minimum exit with an actionable OpenCodex error. It should not terminate the entire proxy with a native trap.
Reproduction
The issue is intermittent rather than deterministically reproducible. The observed sequence was:
- Run OpenCodex 2.11.1 on macOS arm64 and use Codex through the proxy for sustained traffic.
- Open the dashboard with
ocx gui. When no live proxy exists, this starts the proxy in the background. - During a period of network instability, an established upstream connection is reset.
- OpenCodex retries; the retry fails with
unknown certificate verification error. - The next request also fails certificate verification.
- About 0.5–0.6 seconds later, the bundled Bun process exits with
SIGTRAP. - The proxy and dashboard both become unreachable and are not restarted.
This happened twice with the same Bun image UUID, matching main-thread stack offsets, and matching instruction bytes.
Observed timeline (Asia/Shanghai, UTC+8):
- 16:43:47: consecutive TLS verification failure
- 16:43:48.062: Bun PID 61320 crashes with
SIGTRAP - 16:49:33:
ocx guiis run and starts a new proxy process - 17:26:28: consecutive TLS verification failure
- 17:26:29.187: Bun PID 66546 crashes with the same signature
- 17:28:30:
ocx stopappears in shell history, after the crash; it did not cause the outage
There was no OpenCodex launchd service installed, so the detached process was not supervised or restarted after the native crash.
Version
2.11.1
Bundled Bun: 1.3.14
Operating system
macOS 26.5.2, Apple Silicon (arm64)
Provider and model
OpenAI Responses API; observed across multiple GPT models, including gpt-5.6-sol and gpt-5.6-luna.
Logs or error output
# Crash report 1
Report: bun.exe-2026-08-10-164349.ips
Launch: 2026-08-10 15:08:01 +0800
Crash: 2026-08-10 16:43:48.062 +0800
Exception: EXC_BREAKPOINT (SIGTRAP)
Termination: Trace/BPT trap: 5
Faulting thread: main thread
# Crash report 2
Report: bun.exe-2026-08-10-172630.ips
Launch: 2026-08-10 16:49:34 +0800
Crash: 2026-08-10 17:26:29.187 +0800
Exception: EXC_BREAKPOINT (SIGTRAP)
Termination: Trace/BPT trap: 5
Faulting thread: main thread
# Same bundled Bun image in both reports
Image UUID: c7e7a979-f99b-3466-9ad6-e56a63373a35
Matching top image offsets: 52255300, 52218912, 15551472
# Upstream failure sequence immediately before each crash
connection reset
retry attempted
unknown certificate verification error
next fetch: unknown certificate verification error
native Bun SIGTRAP approximately 0.5–0.6 seconds laterThe crash was not a normal shutdown or an apparent macOS Jetsam/OOM termination: both reports record a native SIGTRAP, not SIGKILL, and there was no matching Jetsam report. OpenCodex's JS crash log was not written, which is consistent with a native runtime crash bypassing JS error handling.
Screenshots and supporting files
The complete macOS .ips reports are available locally and can be provided after redaction if maintainers need them. They are not attached initially because they may contain local filesystem paths and process metadata.
Additional observations:
- The two crashes have an identical native signature.
- A comparison of OpenCodex 2.10.2 and 2.11.1 found the same bundled Bun version (1.3.14) and no relevant change in the upstream retry path, so this may be a pre-existing runtime/transport issue exposed by network instability rather than a confirmed 2.11.1 regression.
- The dashboard failure is a consequence of the proxy process crash, not a separate browser failure.
Redacted configuration
{
"port": 10100,
"codexAutoStart": true
}The requests used a local system HTTP(S) proxy. Provider credentials, account data, request bodies, and conversation content have been removed.
Checks
- I searched existing issues and documentation.
- I removed secrets, tokens, account details, request credentials, and personal data.
Activity
Ingwannu commentedon Aug 10, 2026
Thanks for separating the dashboard consequence from the native crash. The two matching SIGTRAP signatures make this credible, but the excerpt is not enough to attribute the trap to an OpenCodex JavaScript path instead of the Bun TLS or system-proxy stack.
Please attach redacted excerpts from both .ips reports containing:
Please also state which proxy mechanism was active (macOS system proxy or PAC, HTTP_PROXY or HTTPS_PROXY, or a local proxy), whether it intercepts TLS or installs a custom CA, and whether the same workload has ever crashed with that proxy disabled. Redact usernames and local paths, but keep image offsets and library names unchanged.
With those frames we can compare or symbolicate the two crashes and determine whether there is an OCX call site to isolate. Marking this as needs-info and leaving it open.
fix(openai-chat): refuse to emit an unnamed streamed tool call (#1531)
fix(server): actually wire the live guard, and cover the passthrough …
fix(responses): leave the combo failure branches unguarded, deliberately
fix(server): settle upstream bodies on the failure paths too (#1539)
lidge-jun commentedon Aug 12, 2026
Investigation update, and hardening landed on
devas #1539 (d03755ee96b7e1e293c3e7ca68a9aba92bb01218). This is not a fix for the crash you reported, and the issue stays open.What was checked
A runtime upgrade is not available. Current stable Bun is
1.3.14(2026-05-13) — the version in your report. Nooven-sh/bunissue establishes that TLS verification failure or a socket reset aborts withSIGTRAP/EXC_BREAKPOINT; the adjacent known defects are hangs andECONNRESET(#31894, #17325).The protections you might expect already ship.
installCrashGuards()(src/lib/crash-guard.ts, called fromsrc/cli/index.ts) installs bothunhandledRejectionanduncaughtExceptionhandlers, redacts and persists diagnostics, and keeps the process alive for JS-level failures. It even special-cases the known Bun abort-teardown rejection. None of that catches a native trap, which is consistent with you seeing no JS crash log.Service supervision exists but does not cover your case. launchd
KeepAlive, systemdRestart=on-failure, and Windows restart-on-failure all ship — butocx guistarts the proxy with a plain detached spawn (src/cli/dispatch.ts), so nothing adopts or restarts it. That is exactly why the dashboard died and stayed dead. Installing the service is a genuine mitigation for that half of the report, and worth doing now regardless of the trap's cause.What landed
An audit of request-path
fetchbody settlement found real unguarded branches, and #1539 fixes them: the non-2xx error branches in the Responses path (translated and native passthrough), both web-search executors, and/v1/live, which had no guard at all and also released its reader lock without cancelling on a failed read.I want to be honest about how that audit went, because it bears on how much weight to put on it. My first pass concluded there were no unguarded sites — that was wrong twice over: it checked whether a guard existed in the function rather than on the branch, and it enumerated candidates from files that already imported the helper, which can only find sites that already have one. Independent review caught both errors. A later revision then broke a real invariant (the combo failure path deliberately reads its body getter exactly once) and CI caught that.
So: these are real defects in the same failure family as your crash, but none of them is demonstrated to be your crash.
What would settle it
The full faulting main-thread frame list from both
.ipsreports, plus the Bun image UUID and load address. That is the discriminator between Bun's TLS/fetch teardown and JavaScriptCore's unhandled-exception path. Until then this stays open.Verification for #1539: full suite 11,334 pass / 0 fail across 698 files; 23 CI checks green including all four Linux shards and macOS;
privacy:scanpass.Wibias commentedon Aug 16, 2026
Triage relationship
Runtime roadmap parent: #1691.
This remains a separate Bun runtime symptom because it has its own reproduction and may need a targeted mitigation before the broader Bun 1.4 qualification program completes.
lidge-jun commentedon Aug 19, 2026
리뷰 · 우선순위 70 / 80
macOS에서 번들 Bun 1.3.14가 연결 리셋과 TLS 검증 실패 직후 SIGTRAP으로 죽으면, ocx stop 없이도 프록시와 ocx gui가 같이 내려갑니다. JS crash.log가 안 남는 것은 네이티브 트랩이 JS 핸들러를 건너뛰기 때문입니다. needs-info가 붙어 있고, 간헐 재현입니다.
현재 package.json bun은 1.3.14입니다. src/cli/index.ts는 installCrashGuards와 스트리밍 오류가 데몬을 죽이지 않게 하는 주석이 있지만, 네이티브 EXC_BREAKPOINT는 그 가드 밖입니다. 이슈는 launchd 서비스가 없어 재시작이 없었다고 합니다. 같은 이미지 UUID와 메인 스레드 오프셋이 두 번 반복된 점은 런타임 버그 쪽을 가리킵니다.
원하는 결과는 일시적 TLS/리셋이 해당 요청만 실패하고 프록시는 살아 있는 것입니다. OpenCodex JS에서 Bun 트랩을 잡을 수는 없습니다. 1691의 Bun 1.4 승격이나 업스트림 수정이 근본 쪽에 가깝습니다. 서비스로 감독하지 않은 ocx gui 백그라운드 프로세스는 죽으면 그대로입니다.
해결방안: 재현 가능한 redacted ips와 네트워크 조건이 더 필요합니다. 제품 완화는 launchd/서비스로 프록시를 감독해 네이티브 종료 후 다시 뜨게 하는 것입니다. TLS 재시도 경로를 JS에서 더 부드럽게 하는 것은 도움이 될 수 있지만, 트랩 자체를 없앤다고 단정하면 안 됩니다. 지금은 패치는 추측하지 않음.
이 댓글은 grok-bot이 작성했습니다
lidge-jun commentedon Aug 25, 2026
Partially addressed on
devby #2633 (1a39adcfa), and I want to be straight about which part.What changed: the bundled runtime already moved from Bun 1.3.14 to 1.4.0 (
27764f342), and that version is now pinned by a test — the existing assertion covered only@types/bun, not the runtime actually shipped, so it could have drifted back silently.What I am not claiming: that the SIGTRAP is fixed. I symbolicated your offsets against Bun's matching binary UUID and got only the crash handler itself:
Those frames say a trap happened, not what trapped. The subsequent frames — the ones that would distinguish TLS/fetch from JSC/GC from another assertion — are not in the report. Bun has 1.3.14 SIGTRAP reports against the same binary UUID, but no upstream issue or release establishes that 1.4.0 fixes this exact signature. Marking this closed on "we bumped the runtime" would be a guess dressed as a fix.
If you can still reproduce, the most useful thing would be the full
.ipswith the frames after the crash handler. That would settle which subsystem is trapping and whether it is even OpenCodex-reachable.One finding worth having regardless of Bun: an installed macOS service is supervised (
RunAtLoad+KeepAlive,src/service.ts:427), so a native crash restarts. Butocx guilaunches an unref'd detached process (src/cli/dispatch.ts:286) — with no installed service, a native crash strands the proxy with no supervisor at all. That is a real difference in blast radius between the two launch paths, and it is the part OpenCodex can act on no matter what the runtime does. Worth its own issue if you agree; I did not add a respawn loop here because that is a lifecycle decision rather than a crash fix.Leaving this open on that basis.
2 remaining items
lidge-jun commentedon Aug 29, 2026
PR #2861 on
devaddresses one concrete part of this: the silent outage. It does not diagnose the SIGTRAP itself.What changed
When the proxy is unreachable,
ocx statusandocx doctorpreviously reported a plain "not running" — indistinguishable from a proxy that was never started. If the process died, its PID file and socket records were left behind, and nothing looked at them.Both commands now probe for that combination: stale process records present, and the recorded port refusing connections at the connect phase specifically. When both hold, they say so, in these words:
The hedge is deliberate. Normal shutdown ignores unlink failures, so leftover records are evidence of an unclean exit, not proof of one. Claiming a crash would be wrong in the case where cleanup simply failed.
Two details worth knowing if you re-test: only a connect-phase
ECONNREFUSEDcounts, because a refusal mid-request means something else entirely; and status and doctor now share one gatherer probing the recorded port, since they previously disagreed when a fallback port was involved.What this does not tell you
Why bundled Bun 1.3.14 takes SIGTRAP after a connection reset with TLS verification failures. Nothing here investigates that. A SIGTRAP from Bun on a reset socket is a runtime-level fault, and the fix above only makes its aftermath visible instead of silent.
Whether your case was in fact an unclean exit. We have no reproduction. This was found by auditing the status path for cases it reports poorly, which your report pointed at.
What would still help
If it recurs on macOS:
ocx statusoutput at that moment — it should now say whether stale records were found.~/Library/Logs/DiagnosticReports/for thebunprocess, which carries the faulting thread and frames. That is the part that could identify the SIGTRAP.Keeping this open for the SIGTRAP itself.
fix(cli): report an unclean prior proxy exit instead of a silent outa…
lidge-jun commentedon Aug 31, 2026
Triaged in the 2026-08-31 bug round and kept open deliberately.
The bundled runtime moved to Bun 1.4.0 in
27764f342, and the stream/TLS capability floor is pinned to it (src/lib/bun-stream-caps.ts:6). A maintainer audit ran 100 self-signed and 100 connection-reset cases against that binary with no SIGTRAP.That is encouraging and it is not proof, which the earlier maintainer comment on this issue already said plainly. Closing this as fixed would claim something nobody has shown: no one has named a Bun change that addresses this trap, and absence of a reproduction on a runtime you were not running is not evidence about your crash.
So it stays open, with the ask unchanged and narrowed to what would actually settle it. If it recurs on Bun 1.4.0:
.ipsfile from ``/Library/Logs/DiagnosticReports/` for the crashed process — the stack frames are the whole pointocx --versionandocx statusat that moment (status now reports stale process records, so it can distinguish an unclean exit from a proxy that never started)Without the frames there is nothing to act on; with them this becomes a concrete change rather than a guess.
lidge-jun commentedon Sep 1, 2026
Re-checked against current
dev. Two things changed since your report, and one thing did not — the one that decides this.What changed
The bundled runtime moved from Bun 1.3.14 to 1.4.0 in
27764f342. That boundary is not arbitrary: 1.4.0 is the first released Bun proven to carry PR #32120, the fix for the Bun#32111 use-after-free that OpenCodex already works around in three places. Your crash is on a runtime we no longer ship.The second half of your report — that an unsupervised native crash left no trace and nothing restarted it — did get addressed.
ocx doctornow detects persisted owner records that outlived their process and says so: "Stale process records remain, so the previous run may have exited unexpectedly." The wording is deliberately cause-neutral, because disk state proves an unclean exit and not which signal caused it.src/cli/doctor.tscites this issue by number for that behavior. A recurrence would now be visible rather than silent.What did not change
Nobody has named a Bun change that fixes this trap. #32111 is a stream-teardown use-after-free; your crash follows two TLS verification failures. Adjacent, not identical. A maintainer audit ran 100 self-signed and 100 connection-reset cases on 1.4.0 without reproducing a SIGTRAP — encouraging, and not proof, since a non-repro on a runtime you were not running says nothing about your crash.
So this stays open. Closing it as fixed would claim something nobody has shown.
The one artifact that would settle it
You noted the
.ipsfiles exist and can be provided after redaction. That is the whole path forward — the crashed thread's frames are what distinguish a TLS-path trap from a stream-teardown one, and without them any change we make is a guess at the crash site.If you still have them, or if it recurs on 1.4.0, the frames matter more than the rest of the file. A redaction that keeps them intact:
Or from the human-readable section, the
Thread 0 Crashed:block. Binary offsets and image names are the useful part; local paths can be stripped freely.Alongside that:
ocx --versionandocx statusat the time, and confirmation that TLS verification failures preceded it as before.Thanks for the original report — the matching image UUID and offsets across two crashes, and your own note that 2.10.2 and 2.11.1 bundled the same Bun so this may predate the version you filed against, are why this was never dismissed as a one-off.
github-actions commentedon Sep 1, 2026
Automated translation bookkeeping — detected language: English.
lidge-jun commentedon Sep 2, 2026
we updated 1.4.0 if their more issue on now please reopen
docs(devlog): regaudit3 recount refreshed (#1419 closed by maintainer…
docs(devlog): bug-label drawdown campaign record and main->dev regres…
fix(cli): report an unclean prior proxy exit instead of a silent outa…
docs(devlog): bug-label drawdown campaign record and main->dev regres…
fix(openai-chat): refuse to emit an unnamed streamed tool call (lidge…
fix(server): settle upstream bodies on the failure paths too (lidge-j…
fix(cli): report an unclean prior proxy exit instead of a silent outa…
docs(devlog): bug-label drawdown campaign record and main->dev regres…